6.3.1为什么引入lambda表达式
是一个可以传递的代码块,可以在以后执行一次或多次,
6.3.2lambda表达式的语法
带参数 变量的表达式就被称为lambda表达式。
//按照字符长度排序 Arrays.sort(planets,(first,second) -> first.length() - second.length());
6.3.3 函数式接口
函数式接口: 对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。
lambda是一个函数而非对象。Java函数没有类型。
java.util.function中定义了很多函数式接口。
Predicate。这个接口专门用来传递lambda表达式。
6.3.4方法引用
字符串排序而不考虑大小写。
Arrays.sort(strings,String::compareToIgnoreCase);
要用::操作分隔方法名与对象或类名。主要有三种情况:
- object::instanceMethod
- Class::staticMethod
- Class::instanceMethod
- super::instance
举例
System.out::println 等价于 x -> System.out.println(x)
Maath::pow 等价于 (x,y) -> Math.pow(x,y)
this::equals等同于 x-> this.equals(x)
6.3.5构造器引用
Person::new
6.3.6变量作用域
lambda表达式就是闭包;
lambda只能引用值不会改变的变量(外围作用域)。
如果在lambda中改变变量,并发执行多个动作时就会不安全。
在lambda中引用变量,而这个变量可能在外部改变,这是不合法的。规则 lambda表达式中捕获的变量必须实际上是最终变量。
lambda表达式的体与嵌套块有相同的作用域。在lambda表达式中声明一个与局部变量同名的参数或局部变量是不合法的。
6.3.7处理lambda表达式
使用lambda表达式的重点是延迟执行。
函数式接口 | 参数类型 | 返回类型 | 抽象方法名 | 描述 | 其它方法 |
---|---|---|---|---|---|
Runable | 无 | void | run | 作为无参数或返回值的动作运行 | |
Supplier< T> | 无 | T | get | 提供一个T类型的值 | |
Consumer< T> | T | void | accept | 处理一个T类型的值 | andThen |
BiConsumer< T,U> | T,U | void | accept | 处理一个T类型的值 | andThen |
Function< T,R> | T | R | apply | 有一个T类型参数的函数 | compose,andThen,identity |
BiFunction< T,U,R> | T,U | R | apply | 有T和U类型参数的函数 | andThen |
自设计的接口,只有一个抽象方法,可以使用@FunctionInterface注解来标记这个接口。有两个优点:
- 非抽象方法检查。
- javadoc页会指出该接口是一个函数式接口。
6.3.8再谈Comparator
静态comparing方法取一个"键提取器"函数,它将类型T映射为一个可比较的类型。
//按名字排序 Arrays,sort(people,Comparator.comparing(Person::getName)); //可以 Arrays,sort(people, Comparator.comparing(Person::getLastName) .thenComparing(Person::getFirstName)); Arrays,sort(people, Comparator.comparing(Person::getLastName)) .(s,t) -> Integer.compare(s.length(),t.length()); Comparator.comparing(p -> p.getName().length())
naturalOrder方法可以为任何实现了Comparable的类建立一个比较器
比较器逆序比较Person [] peoples = new Person[3]; peoples[0] = new Person("a1","a2","a3",19); peoples[1] = new Person("dd","b2","b3",56); peoples[2] = new Person("c1","c2","c3",34); >Arrays.sort(peoples,comparing(Person::getAge,nullsFirst(naturalOrder())).reversed()); System.out.println(peoples); for (Person p: peoples) { System.out.println(p.toString()); }