java8初步-为什么使用lambda表达式

2020-04-08  本文已影响0人  Equals__

1. 前言

lambda表达式 是java8中出现的新语法,那么为什么我们要去使用一种新的语法?或者说为什么我们要把匿名内部类换成lambda表达式?

2.最简单的例子

我们通过一个最简单的例子来查看lambda表达式与匿名内部类的写法区别.

//匿名内部类写法
@Test
    public void test1(){
        Comparator<Integer> com = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
    }
//lambda表达式写法
public void lambda_test1(){
      //o1,o2 为自定义参数,随意替换,意思是compare(Integer o1, Integer o2)方法中的第一个参数和第二个参数,可以写为(x, y) -> Integer.compare(x,y)
       Comparator<Integer> com = (o1, o2) -> Integer.compare(o1,o2);
    }

可以很明显的看出lambda表达式相比较之前的匿名内部类,逻辑清楚,代码简洁,很明显的表达了代码的含义,而最开始的匿名内部类很明显可以感受到有太多多余的代码,其中最关键的就一句话 return Integer.compare(o1,o2),,而其他代码都是多余代码,大大减少了代码的可阅读性.

具体业务中使用

基本数据

假如我们有一个Apple类,代码入下:

@Data //lombok插件自动setter getter
public class Apple {
    private String name; //苹果名字
    private Integer weight; //苹果重量
    private Double  price; //苹果价格

    public Apple() {
    }

    public Apple(String name, Integer weight, Double price) {
        this.name = name;
        this.weight = weight;
        this.price = price;
    }
}

有一个List<Apple>,如下:

ArrayList<Apple> apples = (ArrayList<Apple>) Arrays.asList(
            new Apple("红苹果",3,33.33),
            new Apple("黄苹果",4,44.44),
            new Apple("绿苹果",5,55.55),
            new Apple("毒苹果",6,66.66)
    );

需求来了

现在业务需求来了,我们需要筛选出价格大于50块钱的苹果.那么很明显我们的代码会是这样:

 /**
     * 筛选苹果价格大于50的方法
     */
    @Test
    public List<Apple> test2() {
        List<Apple> filterApple = new ArrayList<>();
        for (Apple apple : apples) {
            if(apple.getPrice() > 50)
                filterApple.add(apple);
        }
        return filterApple;
    }

如果过了两天,项目经理来说我们现在需要筛选苹果重量大于5的方法,那么我们就会复制粘贴上一段代码,然后修改其中的判断部分,代码入下:

/**
* 苹果重量大于5
*/
    @Test
    public List<Apple> test3() {
        List<Apple> filterApple = new ArrayList<>();
        for (Apple apple : apples) {
            if(apple.getWeight() > 5)
                filterApple.add(apple);
        }
        return filterApple;
    }

策略模式优化

可以很明显看到这两端代码,几乎完全是一致的,代码重复率非常之高,在lambda表达式之前,人们只能用设计模式来解决这个问题,比如策略模式,我们会创建一个filter接口,让需要过滤的方法继承filter接口,实现具体的过滤规则.

 /**
     * 通用过滤方法
     * @param apples 需要过滤的List
     * @param myFilter 具体过滤规则
     * @return 过滤结果
     */
 public List<Apple> filterApples(List<Apple> apples, MyFilter myFilter){
        List<Apple> filterApple = new ArrayList<>();

        for (Apple apple: apples) {
            if (myFilter.test(apple))
                filterApple.add(apple);
        }
        return filterApple;
    }

//过滤接口
public interface MyFilter<T> {
    boolean test(T t);
}

而这个时候我们再次实现最开始项目经理提出来的两个需求之后,即可以用通用过滤接口解决问题.

/**
     * 价格大于50 ,策略设计模式改进方法
     * @return
     */
    @Test
    public List<Apple> test5() {
        List<Apple> filterApple = filterApples(this.apples, new MyFilter<Apple>() {
            @Override
            public boolean test(Apple apple) {
                return apple.getPrice() > 50;
            }
        });
        return filterApple;
    }

    /**
     * 重量大于5 ,策略设计模式改进方法
     * @return
     */
    @Test
    public List<Apple> test6() {
        List<Apple> filterApple = filterApples(this.apples, new MyFilter<Apple>() {
            @Override
            public boolean test(Apple apple) {
                return apple.getWeight() > 5;
            }
        });
        return filterApple;
    }

lambda表达式优化

这样我们就实现了代码的复用,大家肯定已经发现了,还可以更加加以改进,那就是使用我们最开始提到的lambda表达式对代码进行优化,让代码更加可读,简洁!

/**
     * 价格大于50 ,lambda改进方法
     * @return
     */
    @Test
    public List<Apple> lambda_test5() {
        List<Apple> filterApple = filterApples(this.apples, (MyFilter<Apple>) apple -> apple.getPrice() > 50);
        return filterApple;
    }

    /**
     * 重量大于5 ,lambda改进方法
     * @return
     */
    @Test
    public List<Apple> lambda_test6() {
        List<Apple> filterApple = filterApples(this.apples, (MyFilter<Apple>) apple -> apple.getWeight() > 5);
        return filterApple;
    }

Stream 搭配lambda表达式优化

相信大家对lambda表达式有一定的了解了,不过其实在实际开发中,遇到这两种需求,可以使用java8中的stream搭配lambda表达式轻松解决.

/**
     * 使用stream 搭配lambda表达式
     * @return 过滤结果
     */
    @Test
    public List<Apple> test7() {
        List<Apple> appleList = apples.stream()  //List Map等都能转化为Stream
                .filter(apple -> apple.getWeight() > 5) //类似于我们的匿名内部类filter的作用
                .collect(Collectors.toList());  //收集器,将Stream 变为List
        return appleList;
    }

小结

上一篇 下一篇

猜你喜欢

热点阅读