lambda的应用场景实例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lambda的应用场景实例相关的知识,希望对你有一定的参考价值。

定义一个POJO类

package com.kotlin.demo.lambda;

import java.time.LocalDate;

public class Person {
    public enum Sex {
        MALE, FEMALE
    }
    String name;
    int age;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public Person(String name, int age, LocalDate birthday, Sex gender, String emailAddress) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
        this.gender = gender;
        this.emailAddress = emailAddress;
    }

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name, int age, Sex gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public int getAge() {
        return this.age;
    }

    public String getName() {
        return name;
    }

    public LocalDate getBirthday() {
        return birthday;
    }

    public Sex getGender() {
        return gender;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

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

    public void setAge(int age) {
        this.age = age;
    }

    public void setBirthday(LocalDate birthday) {
        this.birthday = birthday;
    }

    public void setGender(Sex gender) {
        this.gender = gender;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

    public void printPerson() {
        System.out.println("print person:" + this.toString());
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                ", age=" + age +
                ", birthday=" + birthday +
                ", gender=" + gender +
                ", emailAddress='" + emailAddress + ''' +
                '}';
    }
}

第一种情况:超过指定年龄的人

public static void printPersonsOlderThan(List<Person> roster, int age) {
    for (Person p : roster) {
        if (p.getAge() >= age) {
            p.printPerson();
        }
    }
}
List<Person> personList = new ArrayList<>();
personList.add(new Person("name1", 20, Person.Sex.MALE));
personList.add(new Person("name2", 30, Person.Sex.FEMALE));
personList.add(new Person("name3", 40, Person.Sex.MALE));
personList.add(new Person("name4", 50, Person.Sex.FEMALE));
personList.add(new Person("name5", 60, Person.Sex.MALE));
personList.add(new Person("name6", 70, Person.Sex.FEMALE));
personList.add(new Person("name7", 80, Person.Sex.MALE));

//  通过常规的方法来实现特定的筛选
PersonUtil.printPersonsOlderThan(personList, 30);

第二种情况:筛选一定年龄范围的人

public static void printPersonsWithinAgeRange(List<Person> roster, int low, int high) {
    for (Person p : roster) {
        if (low <= p.getAge() && p.getAge() < high) {
            p.printPerson();
        }
List<Person> personList = new ArrayList<>();
personList.add(new Person("name1", 20, Person.Sex.MALE));
personList.add(new Person("name2", 30, Person.Sex.FEMALE));
personList.add(new Person("name3", 40, Person.Sex.MALE));
personList.add(new Person("name4", 50, Person.Sex.FEMALE));
personList.add(new Person("name5", 60, Person.Sex.MALE));
personList.add(new Person("name6", 70, Person.Sex.FEMALE));
personList.add(new Person("name7", 80, Person.Sex.MALE));

PersonUtil.printPersonsWithinAgeRange(personList, 40, 60);

第三种情况:不知道筛选条件是什么,为了更好的适应将来的情况。定义筛选条件类

public interface CheckPerson {
    boolean test(Person p);
}
public class CheckPersonEligibleForSelectiveService implements CheckPerson {
    @Override
    public boolean test(Person p) {
        return p.gender == Person.Sex.MALE &&
                p.getAge() >= 20 &&
                p.getAge() <= 40;
    }
}

public static void printPersons(List<Person> roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
List<Person> personList = new ArrayList<>();
personList.add(new Person("name1", 20, Person.Sex.MALE));
personList.add(new Person("name2", 30, Person.Sex.FEMALE));
personList.add(new Person("name3", 40, Person.Sex.MALE));
personList.add(new Person("name4", 50, Person.Sex.FEMALE));
personList.add(new Person("name5", 60, Person.Sex.MALE));
personList.add(new Person("name6", 70, Person.Sex.FEMALE));
personList.add(new Person("name7", 80, Person.Sex.MALE));

// 采用已经实现的CheckPerson类来筛选person
PersonUtil.printPersons(personList, new CheckPersonEligibleForSelectiveService());

第四种方式:通过匿名内部类的方式来实现定义的筛选接口,以适应需要的情况

List<Person> personList = new ArrayList<>();
personList.add(new Person("name1", 20, Person.Sex.MALE));
personList.add(new Person("name2", 30, Person.Sex.FEMALE));
personList.add(new Person("name3", 40, Person.Sex.MALE));
personList.add(new Person("name4", 50, Person.Sex.FEMALE));
personList.add(new Person("name5", 60, Person.Sex.MALE));
personList.add(new Person("name6", 70, Person.Sex.FEMALE));
personList.add(new Person("name7", 80, Person.Sex.MALE));

// 通过匿名内部类的形式来实现筛选条件
PersonUtil.printPersons(personList, new CheckPerson() {
    @Override
    public boolean test(Person p) {
        return p.getGender() == Person.Sex.FEMALE
                && p.getAge() >= 40
                && p.getAge() <= 80;
    }
});

第五种方式:通过lambda的方式来替代匿名内部类

List<Person> personList = new ArrayList<>();
personList.add(new Person("name1", 20, Person.Sex.MALE));
personList.add(new Person("name2", 30, Person.Sex.FEMALE));
personList.add(new Person("name3", 40, Person.Sex.MALE));
personList.add(new Person("name4", 50, Person.Sex.FEMALE));
personList.add(new Person("name5", 60, Person.Sex.MALE));
personList.add(new Person("name6", 70, Person.Sex.FEMALE));
personList.add(new Person("name7", 80, Person.Sex.MALE));

// 通过lambda的方式来实现筛选
PersonUtil.printPersons(personList,
        p -> p.getGender() == Person.Sex.MALE
                && p.getAge() >= 40
                && p.getAge() <= 80);

第六种方式:不用自己定义筛选条件类,而采用JDK自带的Funcation

public static void printPersonsWithPredicate(List<Person> roster, Predicate<Person> tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}
List<Person> personList = new ArrayList<>();
personList.add(new Person("name1", 20, Person.Sex.MALE));
personList.add(new Person("name2", 30, Person.Sex.FEMALE));
personList.add(new Person("name3", 40, Person.Sex.MALE));
personList.add(new Person("name4", 50, Person.Sex.FEMALE));
personList.add(new Person("name5", 60, Person.Sex.MALE));
personList.add(new Person("name6", 70, Person.Sex.FEMALE));
personList.add(new Person("name7", 80, Person.Sex.MALE));

PersonUtil.printPersonsWithPredicate(personList,
        p -> p.getGender() == Person.Sex.MALE
                && p.getAge() >= 40
                && p.getAge() <= 80);

Stream的方式处理更多的情况

// 通过lambda的stream来筛选并重新设值
 personList.stream()
         .filter(person -> person.getGender() == Person.Sex.MALE)
         .forEach(person -> person.setEmailAddress("[email protected]"));
         
 String s = personList.stream()
        .filter(person -> person.getGender() == Person.Sex.MALE)
        .map(person -> person.getName())
        .findFirst()
        .get();


总结:通过以上的例子,让我们明白,在有些时候为了代码的健壮性,通常会定义一些中间类来达到我们想要的目标。虽然通过匿名内部类的方式能达到很好的效果,但是其冗余的代码量,增加了代码高度。而采用lambda的形式,使得代码更精简。同时,lambda只让我们实现具体的代码逻辑,至于如何使用这些代码则交给了编译器来处理,而不需要我们来指明这些代买具体的执行方式。而且随着编译器的发展,可能会有更好的优化机制。这样就使得我们只编写逻辑,而不参与代码的具体执行方式。


参考地址:https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html


以上是关于lambda的应用场景实例的主要内容,如果未能解决你的问题,请参考以下文章

片段事务中的实例化错误

Python:lambda表达式的两种应用场景

片段 null 必须是公共静态类才能从实例状态正确重新创建

设计模式 - 应用场景:模板方法模式 + 策略模式 + Lambda

Python基础(十九):函数加强

通过编译lambda表达式来创建实例(可在反射时候用,效率比反射高一些)