- 1.1简介
Java 8 是 Java 语言发展史上的一个重要里程碑,更新了许多新特性,包括 Lambda、流和函数式编程等等。这些特性可以使代码更简洁、易阅读、易维护。Java 程序员必须掌握这些新特性,必须与时俱进,不能 out 哦。
fruits.forEach(f -> {
System.out.println(f.getName());
});
1.2无参数类型
Lambda表达式的基本结构为:f -> {}
f
变量的类型是什么呢?答案是:类型是系统根据上下文 自动 识别的。<br />
Lambda 表达式 {} 内的执行语句,除了能引用参数变量以外,还可以引用外部的变量
因为使用 Lambda 表达式有规范:引用的 局部变量 不允许被修改
我们在《Java面向对象》课程中写过 final 关键字,Lambda 表达式引用的 局部变量 即使不声明为 final,也要具备 final 的特性:变量值初始化后不允许被修改
使用 Lambda 表达式还有一点需要注意:参数不能与 局部变量 同名。下列写法是错误的
String f = "水果名称:";
fruits.forEach(f -> {});
Java 8 支持了一种新的语法:双冒号 “::”,这也是一种 Lambda 写法 ,是与 Lambda 表达式相关的一个重要特性。
names.forEach(System.out::println);
这段代码的重点是使用 :: 时,系统每次遍历取得的元素(n),会 自动 作为参数传递给 System.out.println() 方法打印输出:System.out::println
等同于 n -> {System.out.println(n);}
::
语法干脆省略了参数变量,所以读这段代码需要相互对照、并且自行脑补
**
用法一:静态方法调用
用法二:非静态方法调用
print()
方法不再标识为 static
,于是需要实例对象来调用。
fruits.forEach(new LambdaTest()::print);
只是简写了:
LambdaTest lt = new LambdaTest();
fruits.forEach(lt::print);
效果是一样的。
实际上,本节开头的案例中,System.out::println 语句就是调用非静态方法 println(),因为 System.out 指代的是一个实例对象。只是这个实例对象比较复杂,不是本课程重点
方法三:多参数
Collections.sort(students, (student1, student2) -> {
// 第一个参数的学号 vs 第二个参数的学号
return student1.getRollNo() - student2.getRollNo();
});
就碰到了多参数的情况。如果把比较的过程定义成一个方法:
private static int compute(Student s1, Student s2) {//所在类为 SortTest.java
return student1.getRollNo() - student2.getRollNo();
}
那么排序的过程可以简化为:
Collections.sort(students, SortTest::compute);
注意,系统会 自动 获取上下文的参数,并按上下文定义的 顺序 传递给指定的方法。所谓 顺序 就是 Lambda 表达式 () 中的顺序。
方法四:父类方法
我们在《Java面向对象》学过,super 关键字的作用是在子类中引用父类的属性或者方法。那么同样,:: 语法也可以用 super 关键字调用父类的非静态方法。