在 Java 8中,它的设计者对它做了很多的改革,其中最重大的改革之一就是使用了lambda表达式来简化了行为型模式的开发。行为型模式在实际工作中,是非常有用的一种开发模式。在 Java 8之前,一般都是使用策略模式来实现的。即定义好一个接口规范,然后通过实现这个接口来定义一系列的算法行为。在需要使用这个规范的时候,选择相应的行为即可。
graph TD A[interface] A --> D[class1] A --> E[class2] B[策略模式]public class Student {
private String name;
private int age;
private int grade;
...
}
举个例子,我们这有一个学生集合,学生的属性暂定有姓名、年龄和年级。我们想在这个集合中找到所有一年级的学生,首先我们想到的实现方法就是
List<Student> studentResult = new ArrayList<Student>();
for (Student student : studentList) {
if(student.getGrade() == 1) {
studentResult.add(student);
}
}
但是,需求不可能是一直不变的。例如,现在想得到二年级的所有学生,就需要将原来的代码复制一遍,将条件语句的判断信息改成2。
说到这里,就有人想到了,我可以给这个筛选学生信息的方法传递一个年级参数。当需要不同年级的学生信息的时候,就可以获取相应的信息了。这的确可以解决这个问题,但是如果我想找这个学生列表中学生年龄大于10的学生列表呢?那样的话,是不是还需要在筛选方法中添加一个学生年龄的字段。按照这种方式来拓展的话,就需要一个全属性的筛选方法来定义相应的筛选策略,这样显得就有些笨重了。
还有一种方式,就是通过刚刚提到的策略模式进行来实现一系列算法提供实现。但是,对于某些只使用一次的算法定义一个实现,就显得很冗余了。
Lambda表达式可以在函数式接口上使用。
因此,在Java 8中提供了Predicate接口。在此说明一下,Predicate属于函数式接口,所谓函数式接口,即只有一个抽象方法的接口,而Lambda表达式就是应用在函数式接口上的。
所以,我们的筛选学生的方法就可以这么写:
public static List<Student> getStudent(List<Student> studentList, Predicate<Student> p){
List<Student> studentResult = new ArrayList<Student>();
for (Student student : studentList) {
if(p.test(student)) {
studentResult.add(student);
}
}
return studentResult;
}
好了,现在我们已经把行为的方法定义好了。接下来,我们所需要做的就是通过编写对每个学生的操作的Lambda表达式,来获取我们需要的学生集合。
//一年级的所有学生
List<Student> gradeStudent = getStudent(studentList, student -> student.getGrade() == 1);
//年龄大于10的所有学生
List<Student> ageStudent = getStudent(studentList, student -> student.getAge() > 10);
这样看起来,的确要比为不同的筛选方式定义一种方法要简单、快捷的多。接下来我们可以看看Lambda表达式的定义方式。
Lambda表达式的语法为:
(parameters) -> expression
(parameters) -> {statements;}
刚刚我们提到Lambda表达式能用于函数式接口。就像刚刚我们用到的Predicate,就是一个函数式接口。在Java 8的 java.util.function 包中,提供了很多的函数式接口,Predicate就是其中一种
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*/
boolean test(T t);
...
}
这就是Predicate的部分源码,首先上面的@FunctionalInterface注解代表的是这个接口是函数式接口,当我们自己设计函数式接口的时候可以用上这个注解。然后这个接口里面只有一个抽象方法
boolean test(T t);
因此,我们在使用这个接口的时候,只需要对这个抽象方法进行实现即可,而Lambda表达式就是对这个抽象方法进行实现的。
对Lambda表达式的初步探索就已经完成了,接下来就可以探索更进一步的Java 8特性了。