Java Lambda Map篇
目的
主要介紹Map中的新方法,包含如下
- forEach()
- getOrDefault()
- putIfAbsent()
- remove()
- replace()
- replaceAll()
- merge()
有些是Lambda有些則是我覺得比以前使用Map更方便而介紹
forEach
Map的forEach方法與List不大依樣,因為Map主要的迭代方法是以Entry為主,所以需要Key-Value Pair去迭代
原始碼解說
可以看到forEach的傳入參數BiConsumer介面,必須傳入Key與Val,裡面的實作就如同我們使用Java8版本以前的寫法,需要使用for迴圈去迭代抓出每個Value
原始碼
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
範例
private void forEachExample() {
Map<Integer, String> map = new HashMap<>();
map.put(1, "test1");
map.put(2, "test2");
map.forEach((k,v) -> {
System.out.println("Key : " + k + "- Value : " + v);
});
}
getOrDefault
getOrDefault其實和Lambda沒有太多的關聯,不過!這個方法實在是很好用,我們不須再去判斷Map裡面的Value值是不是存在了,可以直接透過此方法回傳我們想預設的值
範例
private void getOrDefaultExample() {
Map<Integer, String> map = new HashMap<>();
System.out.println(map.getOrDefault(1, "NO_VALUE"));
}
putIfAbsent
如同getOrDefault,都是功能性的方法,當Key對應的值不存在的話,才放入傳入的值
範例
private void putIfAbsentExample() {
Map<Integer, String> map = new HashMap<>();
map.putIfAbsent(1, "original");
map.putIfAbsent(1, "new");
System.out.println(map.getOrDefault(1, "NO_VALUE"));
}
上面的範例,如果實際跑的話可以看到我們拿出來的值是original
remove
其實map本身就有remove參數了,但是他多了一個新的方法,原始碼如下
原始碼解析
可以看到此方法,會將第二個value參數帶入判斷,如果相同才會刪除
原始碼
default boolean remove(Object key, Object value) {
Object curValue = get(key);
if (!Objects.equals(curValue, value) ||
(curValue == null && !containsKey(key))) {
return false;
}
remove(key);
return true;
}
範例
private void removeExample() {
Map<Integer, String> map = new HashMap<>();
map.putIfAbsent(1, "original");
map.putIfAbsent(2, "new");
map.remove(1, "error_value");
map.remove(2);
System.out.println(map.getOrDefault(2, "NO_VALUE"));
System.out.println(map.getOrDefault(1, "NO_VALUE"));
}
replace
replace方法與put方法相似,但重點就如同方法的名稱一樣"替換",當今天此key對應的value存在時才會進行替換,而此方法也提供了三個參數的功能,如果原本存在的Value是這個的話才會進行替換
範例
private void replaceExample() {
Map<Integer, String> map = new HashMap<>();
map.putIfAbsent(1, "original");
map.putIfAbsent(2, "original2");
map.replace(1, "new");
map.replace(2, "original", "new");
map.forEach((k,v)->{
System.out.println(v);
});
}
可以看到上面的範例,original2並不會被new值替換,因為不符合輸入的條件(original)
replaceAll
言簡意賅,直接對Map中的Value值做Side effect處理
範例
private void replaceAll() {
Map<Integer, String> map = new HashMap<>();
map.put(1, "original");
map.put(2, "original2");
map.replaceAll((k, v) -> v.toUpperCase());
map.forEach((k, v) -> {
System.out.println(v);
});
}
merge
merge與replace方法相似,主要差別在於如果原本有值的話則對舊值與新值作傳入的方法處理
範例
private void mergeExample() {
Map<Integer, String> map = new HashMap<>();
map.put(1, "test");
map.merge(1, "new_test", (v1, v2) -> v1 + "-" + v2);
map.forEach((k, v) -> {
System.out.println(v);
});
}
結論
文章介紹了七個Map方法,如果可以實踐的話相信在處理Map結構上,程式碼一定可以更簡潔
留言
張貼留言