經常有一些業務邏輯要用 Map 來解決,如果再多懂得一些 Map 的方法,是可以寫出精簡的 code 的。這裡展示一些優雅處理 Map<K, Collection<T>> 類型的方式。


其實蠻常遇到 Map<K, List<V>> 這樣的集合,當我們想在 key 對應 list 集合裡面添加新 element 時:

Map<K, List<V>> map = new HashMap<>();

// 有可能 NullPointException,因為找不到 key 時 map.get(key) 為null.
map.get(key).add(val);

// 初階處理方式
if(!map.containsKey(key)){
    map.put(key, new ArrayList<>());
}else{
    map.get(key).add(val);
}

// 進階寫法
map.computeIfAbsent(key, k -> new ArrayList<>());
map.get(key).add(val);

接下來是個人比較推薦的寫法。這樣寫也能展現自己對與語言的基礎掌握。

// 優雅寫法
map.computeIfAbsent(key, k -> new ArrayList<>()).add(val);

根據 computeIfAbsent 的特性,使用時有兩種情況;

  • 若 key 不在 map 裡,則會把這個 keyremappingFunction 的 output 添加到 hashMap 裡。 返回值為 remappingFunction 的 output
  • 若 key map 裡,則直接返回 key 對應的 value

因為 ArrayLis t是 reference 引用,故 computeIfAbsent 回傳值和 map.get(key) 是指向地址完全相同的 ArrayList。所以直接 add 是會加到 map 對應的集合裡面的


Guava library 的 Multimap 也不錯,但是需要另外安裝

Multimap<K,V> multimap = ArrayListMultimap.create();
multimap.put(key, val);

Guava 是一個 Goolge 開源的 Java 通用library,核心庫有例如:集合、字串處理、I/O 等工具。


整理

不論是開發還是刷題都很常用到,務必牢記

map.computeIfAbsent(key, k -> new ArrayList<>()).add(val);