• java8之一文彻底弄懂lambda表达式


    Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。而且可以更加适应不断变化的需求;

    下面我们循序渐进从案例入手

    一:传统的应对列表筛选的解决方案

    下面给出一个例子:

    public static List<Apple> filterApple(List<Apple> appleList){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if (Objects.equals(apple.getColor(), "green")){
                    apples.add(apple);
                }
            }
            return apples;
        }

    此代码的意思是从一堆苹果中筛选出绿色的苹果。

    假如哪一天,这位农民伯伯不想筛选绿色的苹果,想筛选红色的苹果,那么我们应该怎么做呢?

    最简单的方法就是将上述的代码复制过来,然后改个条件,

    但是后续的需求变动是不确定,那么我们应该怎么面对这种变化的需求?

    此时进阶的做法就是将条件作为参数传入filterApple方法中,例子如下

    public static List<Apple> filterAppleByCondition(List<Apple> appleList,String color){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if (Objects.equals(apple.getColor(), color)){
                    apples.add(apple);
                }
            }
            return apples;
        }

    上述代码很完美的解决了筛选苹果颜色的各种需求,但是现在要对苹果的重量进行筛选呢?是不是懵逼了,那我们改写一下程序

    public static List<Apple> filterApple(List<Apple> appleList,double weight){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if(Double.compare(apple.getWeight(),weight)>0){
                    apples.add(apple);
                }
            }
            return apples;
        }

    这样也完美的解决了筛选苹果的需求,但是,接下来又有需求要一套方法解决筛选苹果的颜色和重量,改写程序如下

    /**
         * flag 为true则筛选颜色,flag为false筛选重量
         * @param appleList
         * @param color
         * @param weight
         * @param flag
         * @return
         */
        public static List<Apple> filterApple(List<Apple> appleList,String color,double weight,boolean flag){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if((!flag&&Double.compare(apple.getWeight(),weight)>0)||(flag&&Objects.equals(apple.getColor(), color))){
                    apples.add(apple);
                }
            }
            return apples;
        }

    上述代码有以下几个缺点:

    1,flag含义不确定

    2,此方法无法应对更加富有变化的需求

    二,行为参数化

    对筛选苹果这一需求进行建模。

    现在我们的需求是对苹果的属性进行筛选,返回值是一个boolean类型,那么我们建立一个接口

    public interface ApplePredicate {
        public boolean test(Apple apple);
    }

    此接口的实现即可作为筛选苹果的入参,作为一个行为参数传递给筛选苹果的方法

    public class AppleColorPredicate implements ApplePredicate {
        @Override
        public boolean test(Apple apple) {
            return "green".equals(apple.getColor());
        }
    }
    
    
    
    public class AppleWeightPredicate implements ApplePredicate {
        @Override
        public boolean test(Apple apple) {
            return Double.compare(apple.getWeight(),30)>0;
        }
    }

    经过改造后的筛选苹果方法如下:

     public static List<Apple> filterApple(List<Apple> appleList,ApplePredicate predicate){
            List<Apple> apples = new ArrayList<>();
            for (Apple apple : appleList) {
                if(predicate.test(apple)){
                    apples.add(apple);
                }
            }
            return apples;
        }

    这种做法就是借鉴了策略模式。建立一个统一的上层接口,利用不用的实现作为策略;

    我们现在迈出了行为参数化的第一步,但是很遗憾的是,我们的行为必须通过对象的形式传递给方法

    那么,我们有没有办法直接将代码传递给方法呢?有的,lambda表达式

    List<Apple> red = FilterAppleList.filterApple(appleList, apple -> {
                return Objects.equals(apple.getColor(), "red");
            });
  • 相关阅读:
    关于WPF的2000件事 01--WPF是什么?
    生产力
    读书笔记-WPF资源、样式、模板
    泛型
    WebAPI Post方法接收的FromBody一直为null
    第一讲 从头开始做一个web qq 机器人,第一步获取smart qq二维码
    .net dll反编译出现的问题,以及部分修复的方法
    以太坊中私有链的搭建
    java.. C# 使用AES加密互解 采用AES-128-ECB加密模式
    还原数据库出错 解决3154
  • 原文地址:https://www.cnblogs.com/itqczzz/p/13662779.html
Copyright © 2020-2023  润新知