java8中的Predicate && Consumer

java8中的 Predicate && Consumer

最近在看一個(gè)開(kāi)源項(xiàng)目,發(fā)現(xiàn)代碼用了很多jdk8的lambda特性。特來(lái)學(xué)習(xí)總結(jié)一下常用的Predicate和Consumer

Predicate

Predicate用于判斷輸入?yún)?shù)是否滿足某一個(gè)條件,為了更方便地解釋?zhuān)覀兿咕幰粋€(gè)例子
需求: 有一組成績(jī)數(shù)據(jù),要求統(tǒng)計(jì)出所有及格的分?jǐn)?shù)列表。
這個(gè)簡(jiǎn)單,我們隨便寫(xiě)一下就出來(lái)了

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

這個(gè)時(shí)候又來(lái)了一個(gè)新需求,要求統(tǒng)計(jì)出所有及格的,并且分?jǐn)?shù)是奇數(shù)的列表,要怎么寫(xiě)?

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

這個(gè)時(shí)候又來(lái)了一個(gè)新需求,要統(tǒng)計(jì)出所有不及格的分?jǐn)?shù)列表呢?

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

可以看到判斷及格的邏輯被重復(fù)寫(xiě)了好幾遍,如果想盡量復(fù)用應(yīng)該怎么寫(xiě)?答案是把判斷及格的邏輯抽出來(lái),

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());
}

可以看到我們不僅把各種判斷條件抽取了出來(lái),作為單獨(dú)的Predicate方法,還把“選取分?jǐn)?shù)”的模式也抽象出來(lái)了。對(duì)于再有新的過(guò)濾分?jǐn)?shù)的需求,只需要新增具體的Predicate,就可以做各種組合。

Consumer

Consumer會(huì)接受單個(gè)輸入?yún)?shù),并且可能對(duì)參數(shù)值進(jìn)行修改。把“操作”提取成為一個(gè)“操作模式”,可以盡可能地代碼復(fù)用。對(duì)于Consumer,我會(huì)把它理解為excel中的一個(gè)“公式“,滿足條件的某列,都可以應(yīng)用這個(gè)公式生成一個(gè)新的值。
Predicate && Consumer一般會(huì)配合使用, 主要應(yīng)用于這種場(chǎng)景,如果參數(shù)滿足某條件,則對(duì)參數(shù)做某操作。為了更好地說(shuō)明,讓我們?cè)賮?lái)瞎編一個(gè)例子。
需求:又到了一年一度的加薪日,L1的員工每人加薪20%,L2的員工每人加薪15%,使用lambda怎么寫(xiě)

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 +
                    '}';
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容