假設咱們定義下面一個 Map:java
Map<String, List<String>> map = new HashMap<>();
若是咱們要放一個元素進去,不少人會這麼寫:code
List<String> list = map.get("list1"); if (list == null) { list = new ArrayList<>(); map.put("list1", list); } list.add("A");
實際上從 Java 8 開始,Map
提供了 computeIfAbsent()
方法,咱們能夠寫成一行便可:get
map.computeIfAbsent("list1", k -> new ArrayList<>()).add("A");
其中變量 k 是 Map 的 key。io
是否是很方便?可是除此以外,Map 還有兩個方法:getOrDefault()
和 putIfAbsent()
,這三個方法都接受 Key 和一個「默認值」做爲參數,且返回一個 Value。若是不當心把它們搞混用錯了,可能會帶來大問題。下面分別介紹下。class
這個方法有兩個參數,Key 和一個根據 Key 來產生 Value 的 Function;而後返回一個 Value。
這個方法會檢查 Map 中的 Key,若是發現 Key 不存在或者對應的值是 null,則調用 Function 來產生一個值,而後將其放入 Map,最後返回這個值;不然的話返回 Map 已經存在的值。變量
這個方法一樣檢查 Map 中的 Key,若是發現 Key 不存在或者對應的值是 null,則返回第二個參數即默認值。要注意,這個默認值不會放入 Map。因此若是你這樣寫:List
Map<String, List<String>> map = new HashMap<>(); map.getOrDefault("list1", new ArrayList<>()).add("A");
執行完以後 map 仍然是空的!map
這個方法的邏輯徹底不一樣,注意它不是一個 get()
方法,而是 put()
方法的變種!這個方法的邏輯是,若是 Key 不存在或者對應的值是 null,則將 Value 設置進去,而後返回 null;不然只返回 Map 當中對應的值,而不作其餘操做。方法
因此顯而易見,在最開始的例子中,若是將 computeIfAbsent()
替換成其餘兩個方法都是錯的。co