美文网首页
java8中的Predicate && Cons

java8中的Predicate && Cons

作者: rockops | 来源:发表于2018-06-02 22:44 被阅读48次

java8中的 Predicate && Consumer

最近在看一个开源项目,发现代码用了很多jdk8的lambda特性。特来学习总结一下常用的Predicate和Consumer

Predicate

Predicate用于判断输入参数是否满足某一个条件,为了更方便地解释,我们瞎编一个例子
需求: 有一组成绩数据,要求统计出所有及格的分数列表。
这个简单,我们随便写一下就出来了

List<Integer> passList = scoreList.stream()
                .filter(s -> s >= 60 && s <= 100)
                .collect(Collectors.toList());

这个时候又来了一个新需求,要求统计出所有及格的,并且分数是奇数的列表,要怎么写?

List<Integer> passOddList = scoreList.stream()
                .filter(s -> s >= 60 && s < 100 && s % 2 == 1)
                .collect(Collectors.toList());

这个时候又来了一个新需求,要统计出所有不及格的分数列表呢?

List<Integer> failedList = scoreList.stream()
                .filter(s -> s < 60)
                .collect(Collectors.toList());

可以看到判断及格的逻辑被重复写了好几遍,如果想尽量复用应该怎么写?答案是把判断及格的逻辑抽出来,

public static void main(String[] args) {
    List<Integer> passList = filter(scoreList, passPredicate());
    List<Integer> failedList = filter(scoreList, passPredicate().negate());
    List<Integer> passOddList = filter(scoreList, passPredicate().and(isOdd()));
}

private static Predicate<Integer> passPredicate() {
    return x -> (x >= 60 && x <= 100);
}

private static Predicate<Integer> isOdd() {
    return x -> x % 2 == 1;
}

private static List<Integer> filter(List<Integer> originalList, Predicate<Integer> predicate) {
    return originalList.stream().filter(predicate).collect(Collectors.toList());
}

可以看到我们不仅把各种判断条件抽取了出来,作为单独的Predicate方法,还把“选取分数”的模式也抽象出来了。对于再有新的过滤分数的需求,只需要新增具体的Predicate,就可以做各种组合。

Consumer

Consumer会接受单个输入参数,并且可能对参数值进行修改。把“操作”提取成为一个“操作模式”,可以尽可能地代码复用。对于Consumer,我会把它理解为excel中的一个“公式“,满足条件的某列,都可以应用这个公式生成一个新的值。
Predicate && Consumer一般会配合使用, 主要应用于这种场景,如果参数满足某条件,则对参数做某操作。为了更好地说明,让我们再来瞎编一个例子。
需求:又到了一年一度的加薪日,L1的员工每人加薪20%,L2的员工每人加薪15%,使用lambda怎么写

public class ConsumerTest {
    private static Consumer<User> salaryIncreaseConsumer(double ratio) {
        return u -> u.setSalary(u.getSalary() * (1 + ratio));
    }

    private static Predicate<User> levelPredicate(int level) {
        return u -> u.getLevel() == level;
    }

    public static void main(String[] args) {
        User rock = new User("rock", 1, 100);
        System.out.println(rock);
        if (levelPredicate(1).test(rock)) {
            salaryIncreaseConsumer(0.2).accept(rock);
        }
        System.out.println(rock);

        User vivi = new User("vivi", 2, 80);
        System.out.println(vivi);
        if (levelPredicate(2).test(vivi)) {
            salaryIncreaseConsumer(0.15).accept(vivi);
        }
        System.out.println(vivi);
    }

    private static class User {
        private String name;
        private int level;
        private double salary;

        public User(String name, int level, double salary) {
            this.name = name;
            this.level = level;
            this.salary = salary;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getLevel() {
            return level;
        }

        public void setLevel(int level) {
            this.level = level;
        }

        public double getSalary() {
            return salary;
        }

        public void setSalary(double salary) {
            this.salary = salary;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", level=" + level +
                    ", salary=" + salary +
                    '}';
        }
    }
}

相关文章

网友评论

      本文标题:java8中的Predicate && Cons

      本文链接:https://www.haomeiwen.com/subject/syddsftx.html