一个例子简单理解Predicate、Consumer和Stream

一个需求:

把年龄大于20的学生的信息打印出来。

面向对象编程

public class Student {

    private String name;
    
    private int age;
    
    private int number;
    
    public Student(String name,int age,int number){
        this.name = name;
        this.age = age;
        this.number = number;
    }
    
    public String toString(){    
        return "name:"+name+" "+"age:"+age+" "+"number:"+number;
    }

    public int getAge() {
        return age;
    }
    //省略其他get set方法

}
 1 public class Test {
 2 
 3     public static void main(String[] args) {
 4         Student student1 = new Student("ouym",21,1000);
 5         if(student1.getAge()>20){
 6             System.out.println(student1.toString());
 7         }
 8     }
 9     
10 }

如果Test类中line5~7在多处使用,我们还可以将其封装成函数。在Student类中添加函数

public void printIfGTParam(Student student,int age){
        if(student.getAge()>age){
            System.out.println(student.toString());
        }
    }

Test改为如下:

public class Test {

    public static void main(String[] args) {
        Student student1 = new Student("ouym",21,1000);
        student1.printIfGTParam(student1, 20);
    }    
}

但是如果需求变了呢?现在我们需要把名字为ouym的学生信息打印出来。

两个方案:(1)修改printIfGTParam函数,加几个判定条件。但是这明显不符合开闭原则。

(2)添加一个新的函数,处理该需求。如果又有新的需求的话,一直添加代码显得不干净。

下面介绍一个更合理的方法,函数编程。

函数编程

import java.util.function.Consumer;
import java.util.function.Predicate;

public class Student {

    private String name;
    
    private int age;
    
    private int number;
    
    public Student(String name,int age,int number){
        this.name = name;
        this.age = age;
        this.number = number;
    }
    
    public String toString(){    
        return "name:"+name+" "+"age:"+age+" "+"number:"+number;
    }
    
    public void printIf(Predicate<Student> predicate, 
            Consumer<Student> consumer){
        if ( predicate.test(this)){
            consumer.accept(this);
        }
    }

    public int getAge() {
        return age;
    }
   //省略其他set、get方法

}
public class Test {

    public static void main(String[] args) {
        Student student1 = new Student("ouym",21,1000);
        student1.printIf(student -> student.getAge()>20, 
                student -> System.out.println(student.toString()));    
    }
    
}

如果需求改为打印姓名为ouym的学生信息的时候,我们只需要在调用printIf方法的时候把student -> student.getAge()>20改为student -> student.getName()=="ouym"即可。好处不言而喻。这里只是处理一个学生,如果要处理多个学生呢?一个简单的方法是使用for循环,Student类不变,将Test改为如下:

public class Test {

    public static void main(String[] args) {
        Student student1 = new Student("ouym1",19,1000);
        Student student2 = new Student("ouym2",20,1001);
        Student student3 = new Student("ouym3",21,1002);
        Student student4 = new Student("ouym4",22,1003);
        
        List<Student> students = new ArrayList<>();
        students.add(student1);
        students.add(student2);
        students.add(student3);
        students.add(student4);
        
        for(Student one : students){
            one.printIf(student -> student.getAge()>20, 
                    student -> System.out.println(student.toString()));    
        }    
    }
        
}

对于集合的情况,Java8的函数编程也提供了stream接口支持。

public class Test {

    public static void main(String[] args) {
        Student student1 = new Student("ouym1",19,1000);
        Student student2 = new Student("ouym2",20,1001);
        Student student3 = new Student("ouym3",21,1002);
        Student student4 = new Student("ouym4",22,1003);
        
        List<Student> students = new ArrayList<>();
        students.add(student1);
        students.add(student2);
        students.add(student3);
        students.add(student4);
        
        students.stream().filter(student -> student.getAge()>20)
        .forEach(student -> System.out.println(student.toString()));
        
    }    
}

这里只是stream一个简单的操作,更多详情介绍:stream基础教程

猜你喜欢

转载自www.cnblogs.com/ouym/p/8926854.html
今日推荐