美文网首页
java8初步-为什么使用lambda表达式

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

作者: Equals__ | 来源:发表于2020-04-08 00:06 被阅读0次

    1. 前言

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

    • Lambda是一个匿名函数,可以理解为一段可以传递的代码,将代码像数据一样进行传递,可以写出更加简介、更加灵活的代码。作为一宗更紧凑的代码风格,使Java的语言表达能力得到了提升.

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

    小结

    • Lambda是一个匿名函数,可以理解为一段可以传递的代码,将代码像数据一样进行传递,可以写出更加简介、更加灵活的代码。作为一宗更紧凑的代码风格,使Java的语言表达能力得到了提升.
      现在我们对这段话的含义的理解稍稍加深了一些, 通过一些简单的小例子,可以清楚的看到在java8 中使得我们的开发便捷了不知道多少.

    相关文章

      网友评论

          本文标题:java8初步-为什么使用lambda表达式

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