Java8 新特性理解
1.Lambda表达式
lambda表达式经常可表述为一下形式
Consumer<String> con = (s) -> {System.out.println(s);};
con.accept("Hello");
接口名 变量名 = (参数1,参数2) -> {
//代码块
};
看到上面的叙述肯定会很懵,根本就不知道在干嘛。
那我们拆解下来看。
1.1 前半段:Consumer <String
首先你要知道Consumer是一个接口在API这么描述:
public interface Consumer
表示接受单个输入参数并且不返回结果的操作。 与大多数其他功能界面不同, Consumer预计将通过副作用进行操作。
同时我们就可以知道,这种lambda表达式,只适用于接口中的抽象方法。
该Consumer类有一个抽象方法,accept(T t)。这是一个抽象方法所以没有方法体。
在我看来Lambda表达式就是为了当你不想覆盖这么一个抽象方法时,给你提供的一个简便覆盖方法。
那么代码的第一行前半段就可以理解为:
1.接口引用Consumer接口,然后你给了一个泛型String类。
2.你给这个接口引用起了个变量名 con 。
1.2后半段:(s) -> {System.out.println(s);};
首先我们需要理解的是假如不用Lambda表达式,其真实面貌应该是这样的:
Consumer<String> con3 = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
con3.accept("hello");
可以明显的看出来,其实是一个匿名内部类。下面我们来解析一下
1.(s)明显的代表你重写方法中定义的形参 (String s)。
2.接着一个 “->” 箭头指向了后面的 {System.out.println(s);}。当然代表的是覆盖方法中的代码块区。
3.最后调用该方法accept,并输入变量,那么就可以打印出 “hello”的字样。
2.方法引用
Consumer<String> con2 = System.out::println;
con2.accept("hello");
紧接着上面的叙述,方法引用和上面的lambda表达式写的代码不一样,但是执行的功能是一样的。
我们可以看出方法引用比lambda更简洁,直接省略掉了形参,改用 :“对象::方法名”的形式来进行对接口内部抽象方法的覆盖。
System.out是一个对象,而println是该对象所具有的一个方法。跟平常所用的 “对象.方法()”有异曲同工之妙。