全篇简介
菜鸟一名,想了解一下Java8的新型特性在编程时的体现,四处查找资料之后,留下自己理解的读书笔记。(惨兮兮)这一篇想记录的新特性是有关Lambda 表达式的内容。
Lambda 表达式
在 Java8 以前,我们想要让一个方法可以与用户进行交互,比如说使用方法内的局部变量;这时候就只能使用接口做为参数,让用户实现这个接口或使用匿名内部类的形式,把局部变量通过接口方法传给用户。
Lambda 表达式将函数当成参数传递给某个方法,或者把代码本身当作数据处理;
语法格式
- 用逗号分隔的参数列表
- -> 符号
- 和 语句块 组成
版本区别
在以前的版本中想要对对象中的字符进行排列时,所需要的代码量大约是这样。
在使用时一般来说都是用Collections.sort方法,向其中传入需要排序的对象和一个匿名比较对象来创造一个排列顺序。
List<String> names = Arrays.asList("A", "B", "C", "D");
Collections.sort(names, new Comparator<String>() {
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));
而且由于Java编译可以自主的检查出你的对象的类型,所以连String都不需要再重写一次
Collections.sort(names, (a, b) -> b.compareTo(a));
Lambda表达式与匿名内部类的不同与相同
而Lambda 表达式与以前版本的匿名内部类比较重要的不同的区别在于
匿名内部类的调用,在使用this时,调用的就是该匿名内部类中的实例。
Lambda表达式的调用,在使用this时,调用的则是外部类中的实例。
代码理解如下:
这是内部匿名类的this调用
package test;
public class Test{
Test a = this;
Runnable r1 = new Runnable() {
public void run() {
System.out.println((Object) this == a);
}
};
public static void main(String... args) {
new Test().r1.run();
}
}
其返回结果为false
再来看Lambda表达式的this调用
package test;
public class Test1 {
Test1 a = this;
Runnable r1 = () -> System.out.println((Object)this == a);
public static void main(String... args) {
new Test1().r1.run();
}
}
返回结果是true
这两个结果我认为是最能体现Lambda表达式与内部匿名类的区别所在。
这两则代码学习于
java lambda表达式与匿名内部类不是等价关系,lambda不仅仅是语法比匿名内部类更简便
但是我不理解的是为什么要使用Runnable接口。
上面这一则Lambda表达式的特性表明了它与内部匿名类的不同点,但是Lambda表达式本质上来说还是内部匿名类的一个变种及改装,所以它所使用的变量都会隐性的转化为final类。
代码理解如下:
String s = ",";
Arrays.asList( "A", "B", "C" ).forEach( a -> System.out.print( a + s ) );
等价于
final String s = ",";
Arrays.asList( "A", "B", "C" ).forEach( a -> System.out.print( a + s ) );
总结
Lambda 表达式的使用使得java8中对内部与外部函数的调用更加方便,代码变得更加简洁同时也更加容易读懂,它与传统的匿名内部类的使用有相同点也有不同点,这是java8中的一个新特性,后续还会写其他新特性的读书笔记。