你可能會想,toList
和 toSet
都這麼便捷順手了,又怎麼能少得了 toMap()
呢。
答應我,一定打消你的這個想法,否則這將成為你噩夢的開端。
讓我們先準備一個使用者實體類。
@Data @AllArgsConstructor public class User { private int id; private String name; }
假設有這麼一個場景,你從資料庫讀取 User
集合,你需要將其轉為 Map
結構資料,key
和 value
分別為 user
的 id
和 name
。
很快,你啪的一下就寫出了下面的程式碼:
public class UserTest { @Test public void demo() { List<User> userList = new ArrayList<>(); // 模擬資料 userList.add(new User(1, "Alex")); userList.add(new User(1, "Beth")); Map<Integer, String> map = userList.stream() .collect(Collectors.toMap(User::getId, User::getName)); System.out.println(map); } }
執行程式,你已經想好了開始怎麼摸魚,結果啪的一下 IllegalStateException
報錯就拍你臉上,你定睛一看怎麼提示 Key
值重複。
作為優秀的八股文選手,你清楚的記得 HashMap
物件 Key
重複是進行替換。你不信邪,斷點一打,堆疊一看,碩大的 uniqKeys
擺在了面前,憑藉四級 424
分的優秀戰績你頓時菊花一緊,點開一看,誰家好人 map key
還要去重判斷啊。
好好好,這麼玩是吧,你轉身開啟瀏覽器一搜,原來需要自己手動處理重複場景,啪的一下你又重新改了一下程式碼:
public class UserTest { @Test public void demo() { List<User> userList = new ArrayList<>(); // 模擬資料 userList.add(new User(1, "Alex")); userList.add(new User(2, null)); Map<Integer, String> map = userList.stream() .collect(Collectors.toMap(User::getId, User::getName, (oldData, newData) -> newData)); System.out.println(map); } }
再次執行程式,你似乎已經看到知乎的摸魚貼在向你招手了,結果啪的一下 NPE
又拍在你那笑容漸漸消失的臉上。
靜下心來,本著什麼大風大浪我沒見過的心態,斷點堆疊一氣呵成,而下一秒你又望著程式碼陷入了沉思,我是誰?我在幹什麼?
鼓起勇氣,你還不信今天就過不去這個坎了,大手一揮,又一段優雅的程式碼孕育而生。
public class UserTest { @Test public void demo() { List<User> userList = new ArrayList<>(); // 模擬資料 userList.add(new User(1, "Alex")); userList.add(new User(1, "Beth")); userList.add(new User(2, null)); Map<Integer, String> map = userList.stream() .collect(Collectors.toMap( User::getId, it -> Optional.ofNullable(it.getName()).orElse(""), (oldData, newData) -> newData) ); System.out.println(map); } }
優雅,真是太優雅了,又是 Stream
又是 Optional
,可謂是狠狠拿捏技術博文的 G
點了。
這時候你回頭一看,我需要是什麼來著?
這 TM
不是一個迴圈就萬事大吉了嗎,不信邪的你迴歸初心,迴歸了 for
迴圈的懷抱,又寫了一版。
public class UserTest { @Test public void demo() { List<User> userList = new ArrayList<>(); // 模擬資料 userList.add(new User(1, "Alex")); userList.add(new User(1, "Beth")); userList.add(new User(2, null)); Map<Integer, String> map = new HashMap<>(); userList.forEach(it -> { map.put(it.getId(), it.getName()); }); System.out.println(map); } }
看著執行完美無缺的程式碼,你一時陷入了沉思,數分鐘過去了,你刪除了 for
迴圈,換上 Stream
與 Optional
不羈的外衣,安心的提交了程式碼,這口細糠一定也要讓好同事去嘗一嘗。