1:接口的默认方法
java8 允许给接口添加一个非抽象的方法实现,只需要使用default关键字即可
interface Formula{
double calculate(int a);
}
default double sqrt(int a){
return Math.sqrt(a);
}
2:Lambda表达式
老版本的JAVA中排列字符串
List<String> names = Arrays.asList("B","A","C");
Collections.sort(names,new Comparator<String>(){
@Override
public int compare(String a,String b){
return b.compareTo(a);
}
})
JAVA8中如下
Collections.sort(names,(String a,String b) -> {
return b.compareTo(a);
})
或:
Collections.sort(names,(String a,String b) -> b.compareTo(a);)
或:
Collections.sort(names,(a,b) -> b.compareTo(a));
Java编译器可以自动推导出参数类型,所以可以不用再写一次类型。
3:函数式接口
每一个lambda表达式都对应一个类型,通常是接口类型。函数式接口是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。因为默认方法不算抽象方法,所以也可以给函数式接口添加默认方法
可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保接口一定大达到这个要求,只需要给接口添加一个@FunctionalInterface注解,编译器如果发现标注了这个注解的接口有多于一个抽象方法时会报错
@FunctionalInterface interface Converter<F,T>{
T convert(F from);
}
Converter<String,Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
4:方法与构造函数引用
上一节的代码还可以通过静态方法引用表示
Converter<String,Integer> converter = Integer::valueOf;
Integer converted = converter.convert("123");
java8允许使用::关键字来传递方法或者构造函数引用,上面展示了如何引用一个静态方法,也可以引用一个对象的方法
converter = something::startsWith;
String converted = converter.convert("Java");
Soutem.out.println(converted);// J
构造函数使用::关键字引用
class Person{
String firstName;
String lastName;
Person(){};
Person(String firstName,String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
}
指定一个用来创建Person对象的工程接口
interface PersonFactory<P extends Persion>{
P create(String firstName,String lastName);
}
使用构造函数引用将他们关联,而不是实现一个完整的工厂
PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter","Parker");
只需要使用Person::new 获取Person类构造函数的引用,Java编译器会自动根据PersonFactory.create方法签名选择合适的构造函数
5:Lambda作用域
可以直接访问标记了final的外出局部变量,或实例的字段以及静态变量