版权声明:本文为神州灵云作者的原创文章,未经神州灵云允许不得转载。
本文作者:Rujion
在JDK8之前,我们常会使用匿名类来表示一些的代码块,从外部传递方法,但是十分繁琐。在JDK8中,出现了一个新的工具Lambda表达式,同时也引进了一种新的编程方式——函数式编程。
##1.什么是函数式编程
在聊Lambda表达式之前,先聊聊函数式编程。
函数式编程是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。
简单的说,函数式编程更强调的是函数的计算,这使得它方便理解,灵活性更高。函数式编程有几个鲜明的特性:
a)函数是"第一等公民"
“第一等公民”表示函数和其他数据类型一样,可以赋值给变量,可以作为参数或返回值
b)没有"副作用":
所谓"副作用",指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。
函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
c)不修改状态
与上条类似,函数式编程只返回新的值,而不改变变量,
d)引用透明性
即对于相同的输入,函数总是返回相同的结果,也就是说函数表达式是纯粹的,不依赖于其他全局变量或计算顺序等。
相对其他编程方式,函数式编程有着其独特的优势,首先由于其关注计算本身的特点,函数式编程的代码往往比较简洁,同时也利于理解。同时,由于它不依赖于外部,所以方便单元测试与除错。同时由于函数式编程不改变变量,所以他易于并发编程,因为不改变变量,所以线程间不会互相干预或抢占锁。
##2.什么是Lambda表达式:
举个例子:
之前我们对集合进行排序可能是这样的:
List list = new ArrayList<>();
list.sort(new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
使用Lambda表达式后:
List
list.sort((o1, o2) -> o1.compareTo(o2));
是不是显得十分简单易懂。
Lambda表达式通用形式如下:
(parameter1, parameter2,.....) -> {
statsment1
statsment2
......
return ...;
}
即形参 -> 表达式/方法体。
对于单个参数,也可以简化为:
parameter -> {
statsment1
statsment2
......
return ...;
}
对于单个语句,可简化为:
parameter -> stasment
对于函数引用:
1)静态方法引用:
args -> StaticClass.method(args) 等价于 StaticClass :: method
2)实例方法引用:
(args) -> inst.method(args) 等价于 inst :: method
3)对象方法引用:
(inst, args) –> inst.method(args) 等价于 StaticClass :: method
4)构造方法引用:
x->new Class(x) 等价于 Class :: new
##3. Lambda表达式的实现
Lambda表达式其实是Java8对接口实现类的另一方式,避免了代码中的匿名类,但是这也是有一定条件的,这一接口必须是函数式接口 —— 只有一个抽象方法的接口,可以通过 @FunctionalInterface 来修饰。
为了便于开发,Java8 还提供了一些内置接口,方便直接重写。
##4. Lambda表达式的使用
来举个例子:
public class Student {
private int age;
private String name;
private int id;
}
用最简单的排序做个例子:
List
students.sort((std1, std2) -> std1.getAge() - std2.getAge());
进一步的可以使用Comparator内置的方法
List
students.sort(Comparator.comparingInt(Student::getAge));
我们可以将这一Comparator存为静态变量方便调用
public class Student {
private int age;
private String name;
private int id;
public static Comparator BYAGE = Comparator.comparingInt(Student::getAge);
public static Comparator BYNAME = Comparator.comparing(Student::getName);
public static Comparator BYID = Comparator.comparingInt(Student::getId);
}
有时候我们需要对多个字段排序,按照以前的方法,我们可能要多些一个方法或匿名类来进行新的排序,但是使用Lambda表达式,我们就可以复用已经写好的
Comparator。
List students = new ArrayList<>();
students.sort(Student.BYAGE
.thenComparing(Student.BYNAME));
当然,Lambda表达式还有一个重要的使用场景 —— Stream,Stream让我们能非常方便高效的对集合进行各种操作。
例如:
List
List
.sorted(Student.BYAGE)
.map(Student::getName)
.collect(Collectors.toList());
很方便的就取出了按年龄排序后学生的名称列表,而且方便代码阅读与理解,当然Stream结合Lambda表达式还有许多使用方法,这里不一一叙述了,可以看到,Lambda表达式大大精简了代码量,同时也使代码便于理解与复用。
##5. Lambda表达式使用注意
##6.总结
Lambda 的出现为Java带来了函数式编程的新编程方式,使得我们可以用更简洁易懂的代码实现更复杂,更灵活的功能。相信这一新特性也能为代码复用,解耦合带来不少的方便,学习与使用Lambda表达式能为我们的编程带来提高。