java8语言新特性
1.Lambda 表达式 − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
2.方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
3.默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。
4.新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
5.Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
6.Date Time API − 加强对日期与时间的处理。
7.Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
8.Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。
1.Lambda 表达式
Lambda 表达式将函数当成参数传递给某个方法,或者把代码本身当作数据处理;
语法格式:
用逗号分隔的参数列表
-> 符号
和 语句块 组成
Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );
等价于
List<String> list = Arrays.asList( "a", "b", "d" );
for(String e:list){
System.out.println(e);
}
如果语句块比较复杂,使用 {} 包起来
Arrays.asList( "a", "b", "d" ).forEach( e -> {
String m = "9420 " e;
System.out.print( m );
});
Lambda 本质上是匿名内部类的改装,所以它使用到的变量都会隐式的转成 final 的
String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
e -> System.out.print( e separator ) );
等价于
final String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
e -> System.out.print( e separator ) );
Lambda 的返回值和参数类型由编译器推理得出,不需要显示定义,如果只有一行代码可以不写 return 语句
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );
等价于
List<String> list = Arrays.asList("a", "b", "c");
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
函数式接口
接口中只能有一个接口方法
可以有静态方法和默认方法
使用 @FunctionalInterface 标记
默认方法可以被覆写
@FunctionalInterface
public interface FunctionalDefaultMethods {
void method();
default void defaultMethod() {
}
static void staticMethod(){
}
}
private interface Defaulable {
// Interfaces now allow default methods, the implementer may or
// may not implement (override) them.
default String notRequired() {
return "Default implementation";
}
}
private static class DefaultableImpl implements Defaulable {
}
private static class OverridableImpl implements Defaulable {
@Override
public String notRequired() {
return "Overridden implementation";
}
}
// 也可以由接口覆盖
public interface OverridableInterface extends Defaulable{
@Override
public String notRequired() {
return "interface Overridden implementation";
}
}
2.方法引用
方法引用使得开发者可以直接引用现存的方法、Java类的构造方法或者实例对象。方法引用和Lambda表达式配合使用,使得java类的构造方法看起来紧凑而简洁,没有很多复杂的模板代码。
public static class Car {
public static Car create( final Supplier< Car > supplier ) {
return supplier.get();
}
public static void collide( final Car car ) {
System.out.println( "Collided " car.toString() );
}
public void follow( final Car another ) {
System.out.println( "Following the " another.toString() );
}
public void repair() {
System.out.println( "Repaired " this.toString() );
}
}
第一种方法引用的类型是构造器引用,语法是Class::new,或者更一般的形式:Class::new。注意:这个构造器没有参数。
final Car car = Car.create( Car::new );
等价于
Car car = Car.create(() -> new Car());
第二种方法引用的类型是静态方法引用,语法是Class::static_method。注意:这个方法接受一个Car类型的参数
cars.forEach( Car::collide );
forEach 原型为 forEach(Consumer<? super T> action) 使用的是 Consumer 只有参数,没有返回值;这个参数 T 就是 car 类型,因为是 cars.forEach 嘛,所以上面的方法引用等价于
cars.forEach(car -> Car.collide(car));
第三种方法引用的类型是某个类的成员方法的引用,语法是Class::method,注意,这个方法没有定义入参:
cars.forEach( Car::repair );
等价于
cars.forEach(car -> car.repair());