前言:

这两天彻底的复习了一遍Java8的各种新特性,趁着热乎劲,把知识点整理成博客的形式保存一下。



### 一、Lambda介绍
**Lambda表达式 :** 也可称为闭包,Lambda允许把函数作为一个方法的参数(函数作为参数传递到方法中),免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力


语法格式:

(parameters) -> expression

或者

(parameters) ->{ statements; }

格式说明:

():接口中抽象方法的参数列表,没有参数就空着,有参数则写出参数,多个参数用逗号分隔

->:传递的意思,将参数传递给方法体{}

{}:重写接口的抽象方法的方法体

二、Lambda用法实例

1.简单实例(基础用法的规则)

1.1 无参数时,可以省略括号内容
  1. ()->10 //返回结果值:10
1.2 传入String类型的参数
  1. (String s)->System.out.print(s) //打印s的内容
1.3 传入的参数类型可以省略,如下
  1. //
  2. a->a*10 //返回结果值:a*10(传入一个参数时,可以省略括号)
  3. (a,b)->a*b //返回结果值:a*b(传入两个或以上参数时,不能省略括号,)

#### 2.函数式接口
##### 2.1 Lambda实现自定义接口Calculator
首先定义一个函数式接口 ` Calculator `,包含唯一一个抽象方法 ` Calcu() `
```
public interface Calculator {
public abstract int Calcu(int x, int y);
}
```


其次定义一个 ` invokeCalcu() `,接收参数类型为接口
```
public static void invokeCalcu(int x, int y, Calculator calculator) {
int sum = calculator.Calcu(x, y);
System.out.println("sum = " + sum);
}
```


最后调用 ` invokeCalcu() `,一共有两种方法实现:
1)使用匿名内部类传入接口,并实现抽象方法
```
invokeCalcu(10, 20, new Calculator() {
@Override
public int Calcu(int x, int y) {
return x + y;
}
});
```
2)使用Lambda表达式,简化操作
```
invokeCalcu(120, 130, (a, b) -> a + b);
```



##### 2.2 Lambda表达式实现**多线程**接口实例 ` Runnable `
```
//使用匿名内部类的方式实现多线程的创建
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("currentThreadName = " + Thread.currentThread().getName());
}
}).start();

//使用lambda表达式实现多线程

new Thread(() -> System.out.println("currentThread().getName() = " + Thread.currentThread().getName())).start();

  1. <br><hr>
  2. ##### 2.3 Lambda表达式实现**比较器**接口实例 ` Comparator `
  3. 定义一个Person类,保存姓名和年龄

public class Person {

private String name;

private int age;

  1. public Person() { }
  2. public Person(String name, int age) {
  3. this.name = name;
  4. this.age = age;
  5. }
  6. @Override
  7. public String toString() {
  8. return "Person{" +
  9. "name='" + name + '\'' +
  10. ", age=" + age +
  11. '}';
  12. }
  13. public String getName() { return name; }
  14. public void setName(String name) { this.name = name; }
  15. public int getAge() { return age; }
  16. public void setAge(int age) { this.age = age; }

}

  1. <br>
  2. 然后分别使用匿名内部类和Lambda表达式对Person类的年龄进行排序

Person[] arr = {

new Person("佟丽娅", 26),

new Person("范冰冰", 22),

new Person("柳岩", 21)

};

//匿名内部类重写comparator接口里的compare()

System.out.println("=匿名内部类升序排序:===========");

Arrays.sort(arr, new Comparator() {

  1. @Override
  2. public int compare(Person o1, Person o2) {
  3. return o1.getAge() - o2.getAge();
  4. }

});

for (Person person : arr) {

System.out.println(person);

}

//使用Lambda表达式,简化匿名内部类

System.out.println("=Lambda表达式降序排序:=========");

Arrays.sort(arr, (o1, o2) -> o2.getAge() - o1.getAge());

/**

  • jdk1.8 也可以这样写 方法引用
  • Arrays.sort(arr,Comparator.comparingInt(Person::getAge).reversed());

    **/

    for (Person person : arr) {

    System.out.println(person);

    }

//Stream API 也是Java8的新特新写法

System.out.println("=Stream-sort升序排序:=========");

Arrays.stream(arr).sorted(Comparator.comparing(Person::getAge)).forEach(System.out::println);


  1. <br><hr>
  2. > 接口中 **有且仅有唯一一个抽象方法** (接口中可以包含其他私有、默认、静态的方法),称之为函数式接口(这种类型的接口也称为SAM接口,即Single Abstract Method interfaces)
  3. > > **使用前提:**
  4. > > - 使用Lambda必须具有接口,且要求**接口中有且仅有一个抽象方法**
  5. > > - 无论是 JDK内置的 ` Runnable ` 、` Comparator ` 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一时,才可以使用Lambda
  6. > > - 使用Lambda必须具有**上下文推断**
  7. > > - 方法的**参数或局部变量类型**必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例
  8. > > > 有且仅有一个抽象方法的接口,称为 ` “函数式编程” `
  9. ### 三、Lambda变量作用域
  10. ##### 3.1在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量

String[] str = {"1","12","123"};

Comparator comparator = (str, second) -> Integer.compare(str.length(), second.length()); //str处的编译会出错

  1. <br><hr>
  2. #####3.2 Lambda 表达式只能引用标记了 final 的外层局部变量
  3. > 也就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
  4. 可以直接在 lambda 表达式中访问外层的局部变量:

public static void main(String args[]) {

final int num = 1;

Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));

s.convert(2); // 输出结果为 3

}

  1. public interface Converter<T1, T2> {
  2. void convert(int i);
  3. }
  1. <br>
  2. lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

int num = 1;

Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));

s.convert(2);

num = 5; //由于在Lambda表达式中引用了num,所以num是隐形的final修饰,但是这里修改了num的值,final就不存在了

Java8新特性 (一)Lambda的更多相关文章

  1. java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合

    java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...

  2. Java8 新特性学习 Lambda表达式 和 Stream 用法案例

    Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...

  3. Java8新特性系列-Lambda

    转载自:Java8新特性系列-Lambda – 微爱博客 Lambda Expressions in Java 8 Lambda 表达式是 Java 8 最流行的特性.它们将函数式编程概念引入 Jav ...

  4. Java8新特性之Lambda表达式

    lambda表达式是java8给我们带来的几个重量级新特性之一,借用lambda表达式,可以让我们的java程序设计更加简洁.最近新的项目摒弃了1.6的版本,全面基于java8进行开发,本文是java ...

  5. Java8 新特性之Lambda表达式

    1. Lambda 表达式概述 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递); Lambda 表达式可以写出更简洁,更灵活的代码 ...

  6. 【Java8新特性】Lambda表达式基础语法,都在这儿了!!

    写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...

  7. 零基础学习java------21---------动态代理,java8新特性(lambda, stream,DateApi)

    1. 动态代理 在一个方法前后加内容,最简单直观的方法就是直接在代码上加内容(如数据库中的事务),但这样写不够灵活,并且代码可维护性差,所以就需要引入动态代理 1.1 静态代理实现 在讲动态代理之前, ...

  8. 【Java8新特性】- Lambda表达式

    Java8新特性 - Lambda表达式 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! ...

  9. 漫漫人生路-学点Jakarta基础-Java8新特性 Stream/Lambda

    背景 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk dat ...

  10. Java8新特性之Lambda

    为什么要Lambda Java8应该是目前最大的一次更新了,更新后我们迎来了很多新特性,其中便包括Lambda表达式,函数式编程的思想正式进入Java,让我们看一个经典案例. 例1 按照两个人的年龄排 ...

随机推荐

  1. Oracle大表改为分区表及表空间切换方案

    Oracle大表改为分区表及表空间切换方案 一.            背景 由于之前数据库表和索引放在一个表空间导致表空间数据文件增长太快,文件数量即将达到Oracle表空间的限制,需要对表(没有分 ...

  2. Android Studio 打包生成apk

    打开AndroidStudio,并且打开想要生成apk文件的项目  点击工具栏上面的“Builder”  点击“Builder”之后在下拉菜单里面可以看到“Genarate Singed APK”,点 ...

  3. Jenkins系列之-—DevOps高效插件推荐【转】

    基于Jenkins及其插件生态实现自己的持续交付与DevOps平台. jenkins 插件官网 Blue Ocean Jenkins2.7以后可安装,是Jenkins的一种新视图,能够通过图形化的界面 ...

  4. MySQL Install--MySQL安装相关知识和问题

    1.mysqld和mysqld_safe之间关系 mysqld_safe是一个启动脚本,用来启动MySQL服务器并监控MySQL服务的运行情况,并在其服务出现故障宕机后重启其服务. mysql.ser ...

  5. 腾讯微服务框架Tars的初体验

    最近研究了一下腾讯的微服务体系开发框架. 官方的搭建过程:https://github.com/TarsCloud/Tars/blob/master/Install.zh.md 自己填的坑: 不得不说 ...

  6. yum升级curl支持http2测试

    首先,先为你的服务器获取最新匹配的源:http://mirror.city-fan.org/ftp/contrib/yum-repo/ 方法1,rpm方式安装city-fan.org的yum源 # 安 ...

  7. Linux操作系统的计划任务

    Linux操作系统的计划任务 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.任务计划概述 Linux任务计划.周期性任务执行 未来的某时间点执行一次任务: at: 指定时间点, ...

  8. Apache:编译和安装

    1.在Fedora / CentOS / Red Hat Enterprise Linux上安装 sudo yum install httpd sudo systemctl enable httpd ...

  9. 解决shiro多次从redis读取session的问题

    /** * 重写sessonManager * 解决shiro多次从redis读取session的问题 */ public class CustomSessionManager extends Def ...

  10. Javascript技能

    Javascript技能 说一说我对 Javascript 这门语言的一些总结(适合前端和后端研发) 基本认识 一些心得 思维脑图的链接(icloud 分享): https://www.icloud. ...