Java 8新的函数式编程功能
主要有streams, 函数接口, map扩展和新的日期API
接口的缺省方法
Java 8让我们能够增加非抽象方法实现到一个接口中, 使用default
interface formula{
double calculate(int a);
default double sqr(int a){
return Math.sqr(a);
}
}
Lambda表达式
函数接口
每个Lambda表达式对应一个接口类型,也称函数接口。每个Lambda表达式与接口中的抽象方法匹配,接口中只能包含一个抽象方法,但是可以在接口中自由定义多个default方法。
加入元注解**@FuctionalInterface**,保证接口符合只有一个抽象方法的Lambda表达式的要求。
@FunctionalInterface
interface Convert<F,T>{
T convert(F f);
}
Convert<String,Integer> convert = (f) -> Integer.valueOf(f);
方法和构造器的引用
Java8使用符号 :: 实现对方法和构造器的引用。
//静态方法引用
Convert<String,Integer> convert = Integer::valueOf(f);
//普通方法
//相当于传统的子类实现接口,实现接口的抽象方法
//这种方式摆脱了子类对接口的依赖
class Str{
public String test(String str){
return str.charAt(0);
}
}
Str str = new Str();
Convert<String,Integer> convert = str::test(f);
//构造器
class Person {
String firstName;
String lastName;
Person() {}
Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
//工厂方法
interface PersonFactory<P extends Person>{
P create(String firstName,String lastName);
}
//Person:new创建指向Person构造器的引用,自动根据方法签名调用对应构造器
PersonFactory<Person> personFactory = Person::new;
Lambda作用域
-
访问本地变量
Lambda访问外部变量类似于匿名内部类,匿名内部类只能访问final修饰的变量。
Lamdba访问的外部变量可以不是final修饰,但其实这里是隐式final,**一旦被写入Lambda表达式后,变量就不能被修改,无论有无final修饰。**如下:非法int num = 1; Convert<Integer,String> convert = String::valueOf(f); num = 2; //非法
-
访问字段和静态变量
与本地变量相反,可以在Lambda表达式中对其进行读写。 -
接口的默认(default)方法不能被Lambda访问