在上一篇中最后 forEach(): 用到了 Lambda expression,这是 jdk1.8 的新特性。
List<Integer> values = Arrays.asList(4,2,3);
values.forEach(i -> System.out.println(i));
这里就看它是怎么演变过来的:下面这个 demo 很简单,最终输出 『hello lambda』
interface I{
void show();
}
class C implements I {
public void show(){
System.out.println("hello lambda ");
}
}
public class LambdaDemo {
public static void main(String... args){
I obj = new C();
obj.show(); // 输出 hello lambda
}
}
我们先看一眼编译后的 class 文件都有哪些:
一眼就看明白了,没有什么特别的。
因为class C 只是简单的实现了 interface I , 所以可以直接这么写:使用了Anonymous Inner class
interface I{
void show();
}
//class C implements I {
// public void show(){
// System.out.println("hello lambda ");
// }
//}
public class LambdaDemo {
public static void main(String... args){
I obj = new I(){
public void show(){
System.out.println("hello lambda ");
}
};
obj.show();
}
}
然后这个时候再看一下编译后的 class 文件:
这里的Anonymous Inner class 的名字就是最后一个叫:LambdaDemo$1.class
ok, 我们继续
当我们去implements一个interface 再去 rewrite 一个 method 的时候,我们需要考虑的是这个 method的 name , 它的参数列表以及它的 返回值类型,所以在上面的interface I 中已有了 void show(),为什么我还要在下面的实现里再写一遍 public void show() 呢,这样的重复劳动一点也不好。所以下面的
这个时候得到就是:用『->』来代替。
public class LambdaDemo {
public static void main(String... args){
I obj = () -> {
System.out.println("hello lambda ");
};
obj.show();
}
}
当 lambda expression 后面只有一行的时候,是可以把后面的大括号去掉的,所以就变成这样:
public class LambdaDemo {
public static void main(String... args){
I obj = () -> System.out.println("hello lambda ");
obj.show();
}
}
看起来是不是好看多了,也简洁多了,但是这个时候注意一下看它的 class 文件:
看到了吧,很干净,再也没有那个$.class 了。这是 lambda expression 的一个 advantage。awesome !
所以如果当interface I 中的 添加一个 show(int i)有参数的方法时,这个时候的 lambda expression 就可以写成这样了:
I obj = i -> System.out.println("hello lambda " + i);
obj.show(9);
后面这一部分(i -> System.out.println("hello lambda " + i);
)是不是很面熟:
List<Integer> values = Arrays.asList(4,2,3);
values.forEach(i -> System.out.println(i));
这里的i -> System.out.println("hello lambda " + i);
是 interface I 的实现,而 forEach里面的i -> System.out.println(i)
是另外一个 interface 实现,叫做Consumer interface,这个 Consumer interface 是做什么的,后面再说。