一、JDK8为什么引入lambda表达式
理论名词:函数式接口/函数式编程
在代码运行过程中,可以自行判断参数类型。
案例说明:
从一个Student集合中,取出符合要求的元素。
Student.java:
public class Student {
private String name;
private int age;
private int score;
public Student() {
}
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
实现一:
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",14,67));
list.add(new Student("lisi",13,89));
list.add(new Student("wangwu",15,97));
list.add(new Student("maliu",12,63));
list.add(new Student("zhaoqi",17,75));
//查找年龄大于14的学生
findByAge(list);
System.out.println("---------------------");
//查找分数大于75的学生
findByScore(list);
}
private static void findByAge(ArrayList<Student> list) {
ArrayList<Student> result = new ArrayList<Student>();
for(Student s:list){
if(s.getAge() > 14){
result.add(s);
}
}
print(result);
}
private static void findByScore(ArrayList<Student> list) {
ArrayList<Student> result = new ArrayList<Student>();
for(Student s:list){
if(s.getScore() > 75){
result.add(s);
}
}
print(result);
}
//打印结果的函数
public static void print(ArrayList<Student> list){
for(Student s : list){
System.out.println(s);
}
}
}
总结:
会发现findByScore()和findByScore()方法体的实现大体一致,显得代码重复冗余,所以需要进行优化。
两个方法都是提取符合要求的元素,可以想到面向接口编程,将这种要求定义成接口,具体细节由其实现类体现。
实现二(面向接口编程):
为了简化代码,使用原始的匿名内部类的写法
public interface StudentFilter {
//定义一个过滤方法
public boolean compare(Student student);
}
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",14,67));
list.add(new Student("lisi",13,89));
list.add(new Student("wangwu",15,97));
list.add(new Student("maliu",12,63));
list.add(new Student("zhaoqi",17,75));
getByFilter(list, new StudentFilter() {
@Override
public boolean compare(Student student) {
return student.getAge() > 14;
}
});
System.out.println("----------------");
getByFilter(list, new StudentFilter() {
@Override
public boolean compare(Student student) {
return student.getScore() > 75;
}
});
}
public static void getByFilter(ArrayList<Student> students,StudentFilter filter){
ArrayList<Student> list = new ArrayList<Student>();
for(Student student : students){//实质上用了迭代器
if(filter.compare(student)){
list.add(student);
}
}
print(list);
}
//打印结果的函数
public static void print(ArrayList<Student> students){
for(Student student : students){
System.out.println(student);
}
}
}
小结:
如果后续想要增加需求,直接增加StudentFilter的实现子类即可。
实现三(使用lambda表达式)
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",14,67));
list.add(new Student("lisi",13,89));
list.add(new Student("wangwu",15,97));
list.add(new Student("maliu",12,63));
list.add(new Student("zhaoqi",17,75));
//compare(e)->{方法体}
getByFilter(list,(e)->e.getAge() > 14);
System.out.println("----------------");
getByFilter(list,(e)->e.getScore() > 75);
}
public static void getByFilter(ArrayList<Student> students,StudentFilter filter){
ArrayList<Student> list = new ArrayList<Student>();
for(Student student : students){//实质上用了迭代器
if(filter.compare(student)){
list.add(student);
}
}
//打印结果
//forEach的参数类型为Consumer<? super E> action
list.forEach(System.out::println);
}
}
具体说明:
//compare(e)->{方法体}
/*getByFilter()方法的第二个参数是StudentFilter类型,
*且StudentFilter接口中只有一个抽象方法compare
* 所以e是作为该方法的参数,后面的方法体即为compare方法的具体实现
*/
getByFilter(list,(e)->e.getAge() > 14);
//forEach的参数类型为Consumer<? super E> action
//Consumer也是函数式接口,代表一个输入
list.forEach(System.out::println);