• 如何用Java8 Stream API找到心仪的女朋友


    传统的的Java 集合操作是有些啰嗦的,当我们需要对结合元素进行过滤,排序等操作的时候,通常需要写好几行代码以及定义临时变量。
    而Java8 Stream API 可以极大简化这一操作,代码行数少,且易读。

    我们以“找女朋友”为例来看看Java8的Stream API相比传统写法有多香。假设我们定义了一个女朋友类,具有几个关键的指标:姓名,身高,体重,颜值。如下所示:

    class Girl {
        private String name;
        private int height;
        private int weight;
        private int score;
        // 省略get,set及hashCode等方法
    }    
    

    我们有一批适龄女青年名单,如下:

    public static List<Girl> initGirlList(){
        List<Girl> result = new ArrayList<>();
        result.add(new Girl("赵小花",170,60,6));
        result.add(new Girl("钱小花",171,62,7));
        result.add(new Girl("孙小花",172,59,8));
        // 省略.... 
        return result;
    }
    

    心仪女朋友的筛选条件

    假设心仪的女朋友是:体重,身高适中,颜值越高越好。本次设置的条件是找出:身高>=162 并且 体重<=53的女孩,然后按颜值排序前三名。

    Java7的写法

    数据去重

    由于数据可能有重复,这会干扰我们的筛选,因此,第一步先去掉重复数据。代码如下:

    List<Girl> girlList = initGirlList();// 初始化一批数据
    // 数据去重
    List<Girl> distinctGirl = new ArrayList<>();
    for (Girl g: girlList){
        if(!distinctGirl.contains(g)){
            distinctGirl.add(g);
        }
    }
    

    这里new了一个新的distinctGirl来存放去重之后的数据,代码很简单,没啥可说的。

    筛选数据

    下面我们要去掉不合格的数据,本次筛选条件是身高>=162 并且 体重<=53,代码如下:

    // 过滤身高,体重不符合的
    List<Girl> girlTemp = new ArrayList<>();
    for(Girl g: distinctGirl){
        if(g.getHeight() >= 162 && g.getWeight() <= 53){
            girlTemp.add(g);
        }
    }
    

    这里运用上一步中去重之后的distinctGirl,遍历,并将符合条件的放入新的list girlTemp,这里又创建了一个中间list。

    数据排序

    经过上面啰嗦的两步,我们得到了符合我们要求的数据,现在我们需要根据颜值高低进行排名,代码如下:

    Collections.sort(girlTemp, new Comparator<Girl>() {
        @Override
        public int compare(Girl g1, Girl g2) {
            BigDecimal score1 = new BigDecimal(g1.getScore());
            BigDecimal score2 = new BigDecimal(g2.getScore());
            return score2.subtract(score1).intValue();
        }
    });
    

    这里使用了Collections工具类的sort方法,传递了一个匿名类,并在其compare方法中实现了排序的逻辑,这依然是传统集合排序的操作。

    输出结果

    经过上面的几步传统的Java集合操作,我们终于得到了想要的数据。现在我们要输出前三名。

    int i = 1;
    for (Girl g : girlTemp) {
        if(i>=3){
            break;
        }
        System.out.println(g.toString());
    }
    

    OK,至此我们的程序输出了筛选的结果。上面的写法,貌似逻辑很清晰,一步步徐徐渐进。是的,这种传统的写法,Java程序员们已经乐呵呵的写了很多年了。
    一看这个代码足足有20多行!可是实现的逻辑并没有太复杂啊?过阵子你回头看这个代码的话,你多半忘记了这么一大段代码是干嘛的。如果有注释还好,你大概扫一一眼能帮助你快速理清代码做了啥。如果没有注释,你需要逐行去读完这20多行代码,才能明白其逻辑。

    Java8 Stream API的写法

    这里我们在回顾一下,我们的目标:从一个girlList中找出:身高>=162 并且 体重<=53的女孩,然后按颜值排序前三名。Java8的代码如下:

    List<Girl> girlList = initGirlList();
    girlList.stream()
            .filter( g -> g.getHeight() >= 162 && g.getWeight() <= 53)
            .distinct()
            .sorted(Comparator.comparing(Girl::getScore).reversed())
            .limit(3)
            .forEach( g -> System.out.println(g.toString()));
    

    代码6行!并且即使不了解Stream API,且你第一次看这个代码也能猜出是什么意思,filter-过滤,distinct-去重,sort-排序,limit-限制条数,forEach-遍历,就这么简单。

    结语

    Java 这么老语言,如今都Java13了,然而,最具影响的版本我认为还是Java8。我上学那会儿,学校用Java6的写法教学。工作之后开始写Java7的try-with-resource、钻石语法等。一直到现在,市面上很多项目都是Java7。有一次有同事给我说他在前公司写Java8被项目经理说了一顿,我问为啥。他说因为项目经理认为写Java7好维护,团队人人都会写Java7,写Java8的人不多……无语凝噎。

    如果你还没用上Java8,但愿本文中的小例子已经成功的勾起了你用上Java8的兴致。问卷:你现在使用的版本是多少?
    评论下面附了完整源码

    alt 逃离沙漠公众号
    推荐阅读
    Java8系列- 何用Java8 Stream API进行数据抽取与收集
    SpringMVC是怎么工作的,SpringMVC的工作原理
    Mybatis Mapper接口是如何找到实现类的-源码分析
    小程序云开发:菜鸟也能全栈做产品
    CORS详解,CORS原理分析
    工作6年,失业19天
    Docker & k8s 系列一:快速上手docker
    Docker & k8s 系列二:本机k8s环境搭建
    Docker & k8s 系列三:在k8s中部署单个服务实例

  • 相关阅读:
    每天一个Linux命令(03):du命令
    每天一个linux命令(02):route命令
    Ubuntu相关配置
    kvm 虚拟机XML文件
    virtio,macvtap,sriov
    dns配置文件
    Bug预防体系(上千bug分析后总结的最佳实践)
    python-函数
    python实用脚本集
    深入浅出QOS详解(转)
  • 原文地址:https://www.cnblogs.com/demingblog/p/12375663.html
Copyright © 2020-2023  润新知