lambda 简介

Java8 Lambda Expression

对于匿名内部类存在一个问题,如果接口只有一个方法,那么该接口的匿名内部类的实现将看起来很臃肿
如果打算将一个方法作为一个参数传入另一个方法,例如对按钮的点击事件做出响应,那么lambda将帮你实现。
匿名类通常看上去比具名的类更为精简,但是对于只有一个方法的类,那么匿名内部类看起来就有点臃肿了,lambda表达式将可以让你的实现更加优雅。

使用lambda的几个场景的场景.

场景1,从列表中找出符合条件的人员(年龄大于18岁的人)

public class Person {
    public enum Gender{
        MALE, FEMALE
    }
    private String name;
    private Gender sex;
    private Integer age;
    public String getInfo(){
        return toString();
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", age=" + age +
                '}';
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public Gender getSex() {
        return sex;
    }
    public void setSex(Gender sex) {
        this.sex = sex;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}


public class Demo {
    public static void main(String[] args) {
        List<Person> ps = new ArrayList<Person>();
        getAgeOlderThan(ps,18);
    }   

    public static void getAgeOlderThan(List<Person> ps, int age) {
        for (Person p: ps) {
            if(p.getAge() > age){
                System.out.println(p.getInfo());
            }
        }
    }
}

场景2,如果上面的查询条件变动,那就需要重写代码(查询条件改为,在50岁与18岁之间的人)

public class Demo {
    public static void main(String[] args) {
        List<Person> ps = new ArrayList<Person>();
        getAgeBetween(ps,18,50);
    }   

    public static void getAgeBetween(List<Person> ps, int down,int up) {
        for (Person p: ps) {
            if(p.getAge() > down && p.getAge() < up){
                System.out.println(p.getInfo());
            }
        }
    }
}

场景3,可以看到上面的实现,每当出现一个新的查询条件,都需要新添加一个方法,我们想到引入接口使用多态来覆盖不同场景,引入用来做判断的接口PersonChecker和他的实现类CheckPersonWithGender。如果需要修改需求,只需要在添加一个实现类,比方说通过name来查找,只需要额外添加要给CheckPersonWithName类。

public interface CheckPerson {
    boolean check(Person p);
}

// 找出所有性别为指定类型的人
public class CheckPersonWithGender implements CheckPerson{
    @Override
    public boolean check(Person p) {
        if(p.getSex().equals(Person.Gender.FEMALE)){
            return true;
        }
        return false;
    }
}

// 找出所有名字为pikzas的人
public class CheckPersonWithName implements CheckPerson{
    @Override
    public boolean check(Person p) {
        if(p.getName().equals("pikzas")){
            return true;
        }
        return false;
    }
}

public class Demo {
    public static void main(String[] args) {
        List<Person> ps = new ArrayList<Person>();
        getByFilter(ps,new CheckPersonWithGender());
        getByFilter(ps,new CheckPersonWithName());
    }   

    public static void getByFilter(List<Person> ps,CheckPerson checker) {
        for (Person p: ps) {
            if(checker.check(p)){
                System.out.println(p.getInfo());
            }
        }
    }
}

场景4,上面的接口的引入方便了我们使用多态来扩展系统,但是每针对一个特定的过滤条件,我们都需创建一个新的接口实现类,于是可以通过匿名类的方式来将实现简化

public class Demo {
    public static void main(String[] args) {
        List<Person> ps = new ArrayList<Person>();
        // 此处通过匿名类的方式避免了新创建一个类
        getByFilter(ps,new CheckPerson(){
            @Override
            public boolean check(Person p) {
                return p.getAge() > 50;
            }
        });
    }   

    public static void getByFilter(List<Person> ps,CheckPerson checker) {
        for (Person p: ps) {
            if(checker.check(p)){
                System.out.println(p.getInfo());
            }
        }
    }
}

场景5,可以看到上面通过内部类的方式已经使代码相当精简,但是还是有内部类的存在,于是便在Java8中推出了Lambda来替换这种只有一个方法需要实现的内部类,将代码再次简化。

public class Demo {
    public static void main(String[] args) {
        List<Person> ps = new ArrayList<Person>();
        // 此处通过匿名类的方式避免了新创建一个类
        // 此处通过一个lambda表达式清晰明了的替换了一大堆内部类的实现
        getByFilter(ps,(Person p) -> p.getAge() > 18);
    }   

    public static void getByFilter(List<Person> ps,CheckPerson checker) {
        for (Person p: ps) {
            if(checker.check(p)){
                System.out.println(p.getInfo());
            }
        }
    }
}

场景6,上面用(Person p) -> p.getAge() > 18 替换了匿名内部类,主要是需要对数据做逻辑判断的接口CheckPerson的实现。但是该接口在Java8中有官方给定的一个替代接口,java.util.function.Predicate<T>,于是又可以少定义一个接口。

public interface CheckPerson {
    boolean check(Person p);
}
// 替换为
interface Predicate<T> {
    boolean test(T t);
}
public class Demo {
    public static void main(String[] args) {
        List<Person> ps = new ArrayList<Person>();
        //
        getByFilter(ps, p -> p.getAge() > 18);
        getByPreditor(ps, (Person p) -> p.getAge() < 50);
    }
    public static void getByFilter(List<Person> ps,CheckPerson checker) {
        for (Person p: ps) {
            if(checker.check(p)){
                System.out.println(p.getInfo());
            }
        }
    }
    // 使用 Predicate<Person> checker 替换了 CheckPerson checker 进一步抽象,使接口变得更为通用
    // 对应用来做条件判定的方法变为Predicate中的test方法
    public static void getByPreditor(List<Person> ps,Predicate<Person> checker) {
        for (Person p: ps) {
            if(checker.test(p)){
                System.out.println(p.getInfo());
            }
        }
    }
}

场景7,上面的例子都是简单的将符合条件的对象打印了出来,同理于官方定义Predicate<T>用来对数据做过滤,Java8还提供了一个接口Consumer<T>来定义对满足条件的数据该执行的动作。

public interface Consumer<T> {
    void accept(T t);
public class Demo {

    public static void main(String[] args) {
        List<Person> ps = new ArrayList<Person>();
        // 此处通过匿名类的方式避免了新创建一个类
        getByFilter(ps, p -> p.getAge() > 18);
        getByPreditor(ps, p -> p.getAge() < 50);
        getByPreditorAndActByConsumer(
            ps,
            p-> p.getAge() > 18 && p.getAge() < 50, // 对Predicate接口中test方法的实现
            p -> System.out.println(p.getInfo()));  // 对Consumer接口中accept方法的实现
    }

    public static void getByFilter(List<Person> ps, CheckPerson checker) {
        for (Person p : ps) {
            if (checker.check(p)) {
                System.out.println(p.getInfo());
            }
        }
    }

    public static void getByPreditor(List<Person> ps, Predicate<Person> checker) {
        for (Person p : ps) {
            if (checker.test(p)) {
                System.out.println(p.getInfo());
            }
        }
    }

    // 对符合条件的数据应用动态的处理方式
    public static void getByPreditorAndActByConsumer(List<Person> ps, Predicate<Person> checker, Consumer<Person> consumer) {
        for (Person p : ps) {
            if (checker.test(p)) {
                consumer.accept(p);
            }
        }
    }

}

https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#syntax

lambda的格式

猜你喜欢

转载自www.cnblogs.com/Pikzas/p/12146413.html
今日推荐