1. 程式人生 > >不要再寫這樣的神級程式碼了!

不要再寫這樣的神級程式碼了!

JDK8提供的Stream雖然好用,Lambda雖然簡潔,但一定不能**濫用**,我舉一個實際遇到的例子(已做脫敏處理): ```java Map> 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)); ``` 試問誰能看得懂?難道是沒有換行格式化? ```java Map> 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這樣的神奇幫助我們,滑鼠移動到程式碼處,點選右鍵出現以下選單: ![](https://img2020.cnblogs.com/blog/630246/202003/630246-20200321213329871-1317185663.jpg) 點選“Show Context Actions”,出現以下內容: ![](https://img2020.cnblogs.com/blog/630246/202003/630246-20200321213340369-187524759.png) 選擇“Replace Stream API chain with loop(利用迴圈代替Stream流操作)”。 當我把所有的Stream流操作以及簡寫的lambda表示式用“傳統”程式碼取代後,程式碼邏輯如下: ```java Map> map = new HashMap<>(); //按step進行分組 for (Student student : students) { //computeIfAbsent方法等同下列程式碼 /*List list = map.get(student.getStudentNumber()); if (list == null) { list = new ArrayList<>(); map.put(list); } list.add(student)*/ map.computeIfAbsent(student.getStudentNumber(), new Function>() { @Override public List apply(Long k) { return new ArrayList<>(); } }).add(student); } //把Map的Entry元素放入List中,並排序 List>> toSort = new ArrayList<>(); for (Map.Entry> integerListEntry : map .entrySet()) { toSort.add(integerListEntry); } toSort.sort(Map.Entry.comparingByKey()); //再使用LinkedHashMap按插入順序排列 Map> studentkMap = new LinkedHashMap<>(); for (Map.Entry> integerListEntry : toSort) { studentkMap.putIfAbsent(integerListEntry.getKey(), integerListEntry.getValue()); } ``` 這樣看程式碼邏輯清晰了,實際上不就是把List按元素中的step分組,並按字典序排列麼?如果按照開始的Stream+Lambda表示式,別說優化,連看懂都是問題。當我們把程式碼改為“傳統”程式碼後,邏輯一下就清晰了。 ```java Map>> studentMap = new TreeMap<>(); for (Student student : students) { List list = map.get(student.getStudentNumber()); if (list == null) { list = new ArrayList<>(); map.put(list); } list.add(student) } ``` 適當是使用Stream和Lambda這樣是不是更好呢? 關注公眾號(**CoderBuff**)回覆“**stream**”獲取《Java8 Stream編碼實戰》PDF完整版。 ![](https://pic-1255645163.cos.ap-chengdu.myqcloud.com/目錄.png) 這是一個能給程式設計師加buff的公眾號 (CoderBuff)