欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

不要再写这样的神级代码了!

程序员文章站 2022-06-15 14:01:12
JDK8提供的Stream虽然好用,Lambda虽然简洁,但一定不能 滥用 ,我举一个实际遇到的例子(已做脱敏处理): 试问谁能看得懂?难道是没有换行格式化? 换行格式化后,前面的流操作还能勉强读懂,遇到最后的lambda表达式实在没办法读下去了,根本不知道他想表达什么意思。 但是,如果我们真正遇到 ......

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)
不要再写这样的神级代码了!