• java8 学习之路之lambda


     前言

      目前我们知道java的版本已经发布到12了,之前的项目用的是JDK1.7,听说JDK1.8的改动相对来说大一些,因此抽空学学JDK1.8的一些新特性。本人也是通过阅读Java8实战这本书做一些小的总结,方便以后巩固,同时也为想学习Java1.8的人提供一些思路望大家多多包涵,有不对的地方请提出了我们一起学习。想要Java8实战这本书电子版的小伙伴可以留言告我可以发给你呦!

     演变过程

      这里我们通过一个简单的故事来引出神奇的Lambda。这里首先有一个苹果的实例,其包含简单的属性:颜色和重量。

     1 public class Apple {
     2     private int weight = 0;
     3     private String color = "";
     4 
     5     public Apple(int weight, String color){
     6         this.weight = weight;
     7         this.color = color;
     8     }
     9     // get/set/toString  
    10 }

      首先我们要获取红色的苹果(因为红色的好吃嘛),这时候我们会定义一个简单的方法来进行过滤获取到红色的苹果。

     1     /**
     2      * 筛选红苹果
     3      * @param inventory
     4      * @return
     5      */
     6     public static List<Apple> filterRedApples(List<Apple> inventory){
     7         List<Apple> result = new ArrayList<>();
     8 
     9         for (Apple apple: inventory){
    10             if ("red".equals(apple.getColor())) {
    11                 result.add(apple);
    12             }
    13         }
    14 
    15         return result;
    16     }

      后来由于苹果收购商有来了,我不管什么苹果,只要重量大于150g的统统给我装上车!好办啦!我们再加个方法来进行过滤就可以了。

        /**
         * 筛选重量大于150的苹果
         * @param inventory
         * @return
         */
        public static List<Apple> filterHeavyApples(List<Apple> inventory){
            List<Apple> result = new ArrayList<>();
    
            for (Apple apple: inventory){
                if (apple.getWeight() > 150) {
                    result.add(apple);
                }
            }
    
            return result;
        }

      过了几天水果商又来了,我们现在想要绿色的苹果。这时候你可能想到是加一个方法 filterGreenApples 专门过滤绿色苹果,然而,如果要筛选多种颜色呢?黄色?暗红色?难道我们要每个新加一个方法吗?当然不是!我们最开始想到的是吧颜色作为参数传进去,试着将其抽象化。

     1     public static List<Apple> filterApplesByColor(List<Apple> inventory,
     2                                                   String color) {
     3         List<Apple> result = new ArrayList<Apple>();
     4 
     5         for (Apple apple: inventory){
     6             if ( apple.getColor().equals(color) ) {
     7                 result.add(apple);
     8             }
     9         }
    10 
    11         return result;
    12     }

      同时我们可能想到将获取重量的方法也进行优化

     1     public static List<Apple> filterApplesByWeight(List<Apple> inventory,
     2                                                    int weight) {
     3         List<Apple> result = new ArrayList<Apple>();
     4 
     5         for (Apple apple : inventory){
     6             if ( apple.getWeight() > weight ){
     7                 result.add(apple);
     8             }
     9         }
    10 
    11         return result;
    12     }

      这时候就很不错了,可(cao)爱(dan)的水果商又来了让我们提供一种方式来区分不同的属性进行过滤。OK! 我们进行优化!

     1     public static List<Apple> filterApples(List<Apple> inventory, String color,
     2                                            int weight, boolean flag) {
     3         List<Apple> result = new ArrayList<Apple>();
     4 
     5         for (Apple apple: inventory){
     6             if ( (flag && apple.getColor().equals(color)) ||
     7                     (!flag && apple.getWeight() > weight) ){
     8                 result.add(apple);
     9             }
    10         }
    11 
    12         return result;
    13     }

      你会发现这个方法中的flag很难让人读懂。而且如果水果商想要再根据不同的属性进行过滤呢?比如产地、形状,那么这个方案就不能满足我们的需求了。

       那么我们如何应对这种多变的需求呢?让我们来定义一个接口对苹果过滤器进行建模。

    1 public interface AppleFilter {
    2     boolean test(Apple apple);
    3 }

      我们定义一个接口对苹果进行过滤,你可以定义多个实现类来选择不同的标准。

     1 public class AppleGreenColorFiler implements AppleFilter {
     2     @Override
     3     public boolean test(Apple apple) {
     4         return "green".equals(apple.getColor());
     5     }
     6 }
     7 
     8 public class AppleHeavyWeightFilter implements AppleFilter {
     9     @Override
    10     public boolean test(Apple apple){
    11         return apple.getWeight() > 150;
    12     }
    13 }

      这种实现方式类似与策略模式,我们可以将这种行为的实现作为一个参数传递进去。

     1     public static  List<Apple> filterApples(List<Apple> inventory, AppleFilter appleFilter) {
     2         List<Apple> result = new ArrayList<Apple>();
     3 
     4         for (Apple apple : inventory) {
     5             if(appleFilter.test(apple)) {
     6                 result.add(apple);
     7             }
     8         }
     9 
    10         return result;
    11     }

      这时候我们会发现我们的代码灵活很多了,可以应对水果商的各种需求了。而过滤的主要业务我们是在其实现类中进行定义的。我们甚至可以同时获取重量大于150并且是红色的苹果。

    1 public class AppleRedAndHeavyFilter implements AppleFilter {
    2     @Override
    3     public boolean test(Apple apple) {
    4         return "red".equals(apple.getColor()) && apple.getWeight() > 150;
    5     }
    6 }

      这时候我们发现我们可以使用匿名内部类做代码的优化。并不需要每次都创建其实现类来完成。

    1 List<Apple> redApples = filterApples(inventory, new AppleFilter() {
    2     @Override
    3     public boolean test(Apple apple) {
    4         return "red".equals(apple.getColor());
    5     }
    6 });

      那么在Java8中我们怎么做呢?看好啦!

    1 List<Apple> redApples = filterApples(inventory, (Apple apple) -> "red".equals(apple.getColor()));

      这样的代码即简洁又容易读懂。

    其他例子

      其实这样的写法可以针对很多地方,例如我们在使用Comparator对集合中的数据进行排序的时候,再比如使用Runnable创建线程的时候。这里就不再举例了,希望大家自己在下面试试这几种方式。

  • 相关阅读:
    cdn服务器
    面向对象---特----性
    我自己总结的一些知识点--分享
    进程与线程的区别
    centos忘记root用户的密码
    svn上传时显示database is locked
    公司memcache安装方式及启动方式
    阿里云挂载快照盘
    阿里云卸载磁盘是报错
    scp
  • 原文地址:https://www.cnblogs.com/brother-four/p/10675766.html
Copyright © 2020-2023  润新知