zoukankan      html  css  js  c++  java
  • 不要再写这样的神级代码了!

    关注公众号(CoderBuff)回复“stream”获取《Java8 Stream编码实战》PDF完整版。

    JDK8提供的Stream虽然好用,Lambda虽然简洁,但一定不能滥用,我举一个实际遇到的例子(已做脱敏处理):

    Map<Long, List<Student>> studentMap = students.stream().collect(Collectors.groupingBy(Student::getStudentNumber)).entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
    

    试问谁能看得懂?难道是没有换行格式化?

    Map<Long, List<Student>> studentMap = students.stream().collect(Collectors.groupingBy(Student::getStudentNumber))      //这里是要把students按studentNumber分组
                    .entrySet().stream().sorted(Map.Entry.comparingByKey())     //分组后再把把key值拿来排序组成新的Stream流
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,       //然后再组成Map?不好意思实在是读不下去了
                            (oldValue, newValue) -> oldValue, LinkedHashMap::new));
    

    换行格式化后,前面的流操作还能勉强读懂,遇到最后的lambda表达式实在没办法读下去了,根本不知道他想表达什么意思。

    但是,如果我们真正遇到这样的“大神级”代码怎么办?还好有IDEA这样的神奇帮助我们,鼠标移动到代码处,点击右键出现以下菜单:

    点击“Show Context Actions”,出现以下内容:

    选择“Replace Stream API chain with loop(利用循环代替Stream流操作)”。

    当我把所有的Stream流操作以及简写的lambda表达式用“传统”代码取代后,代码逻辑如下:

    Map<Long, List<Student>> map = new HashMap<>();
    //按step进行分组
    for (Student student : students) {
      	//computeIfAbsent方法等同下列代码
      	/*List<Student> list = map.get(student.getStudentNumber());
         if (list == null) {
             list = new ArrayList<>();
             map.put(list);
         }
         list.add(student)*/
        map.computeIfAbsent(student.getStudentNumber(), new Function<Long, List<Student>>() {
            @Override
            public List<Student> apply(Long k) {
                return new ArrayList<>();
            }
        }).add(student);
    }
    //把Map的Entry元素放入List中,并排序
    List<Map.Entry<Long, List<Student>>> toSort = new ArrayList<>();
    for (Map.Entry<Long, List<Student>> integerListEntry : map
            .entrySet()) {
        toSort.add(integerListEntry);
    }
    toSort.sort(Map.Entry.comparingByKey());
    //再使用LinkedHashMap按插入顺序排列
    Map<Long, List<Student>> studentkMap = new LinkedHashMap<>();
    for (Map.Entry<Long, List<Student>> integerListEntry : toSort) {
        studentkMap.putIfAbsent(integerListEntry.getKey(), integerListEntry.getValue());
    }
    

    这样看代码逻辑清晰了,实际上不就是把List按元素中的step分组,并按字典序排列么?如果按照开始的Stream+Lambda表达式,别说优化,连看懂都是问题。当我们把代码改为“传统”代码后,逻辑一下就清晰了。

    Map<Long, List<Student>>> studentMap = new TreeMap<>();
    for (Student student : students) {
        List<Student> list = map.get(student.getStudentNumber());
        if (list == null) {
            list = new ArrayList<>();
            map.put(list);
        }
        list.add(student)
    }
    

    适当是使用Stream和Lambda这样是不是更好呢?

    关注公众号(CoderBuff)回复“stream”获取《Java8 Stream编码实战》PDF完整版。

    这是一个能给程序员加buff的公众号 (CoderBuff)
  • 相关阅读:
    LVS-三种负载均衡方式比较
    keepalived和heartbeat区别
    vmware-question
    SQL Server MYSQL 检查点的好处
    MYSQL 引擎的情况
    MYSQL 关闭服务的过程
    SQL Server 行的删除与修改-------------(未完待续P222 deep SQL Server 222 )
    SQL Server一些重要视图 1
    SQL Server 查看数据页面
    SQL Server 向堆表中插入数据的过程
  • 原文地址:https://www.cnblogs.com/yulinfeng/p/12542417.html
Copyright © 2011-2022 走看看