Jdk 1.8-Map接口新方法-201804
用例:
Map<String,String> map=new HashMap<>();
String[][] user= {{"harry","123"},{"kann","ff"},{"bob","fe88"},{"felton","okjj"}};
for(String[] u:user) {
map.put(u[0], u[1]);
}
1. default V compute(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction)
計算K,V之間映射關係,根據重映射函數返回新的V值,若返回null,直接刪除該組映射.(如果最初不存在則保持不存在)。 如果重映射函數本身引發(未檢查)異常,則重新引導異常,並且當前映射保持不變。BiFunction接口的apply的入參爲key、oldValue。
//此時Harry的字符串長度>"123",則返回null,此組映射被直接刪除
map.compute("harry", (k,v)->k.length()>v.length()?null:v);
map.forEach((k,v)->System.out.println(k+"-"+v));
//注意不要在計算過程中修改該映射,否則拋出ConcurrentModificationException[map本身的default方法並未throw exception,但其實現類都應重寫拋出該異常]
// map.compute("kann", (k,v)->{
// return map.remove("kann");
// });
2.default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
//if K-V值缺失,then 計算
/**若lambda式返回值!=null, 且Key不存在, 則在map中新增該組(K,V);
* 且若Key存在, 且原value!=null,則不做操作;
* 但原value=null,則更新value值;
* 若lambda式返回值=null, 則不做操作;
*/
String empty=map.computeIfAbsent("harry", v->null);
map.computeIfAbsent("grant", v->"jjjds");
map.computeIfAbsent("felton", v->null);
System.out.println(empty);
map.forEach((k,v)->System.out.println(k+"-"+v));
3.default V computeIfPresent(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction)
/**如果指定的密鑰的值存在且非空,則嘗試計算給定密鑰及其當前映射值的新映射。 如果重
* 映射函數返回null ,則映射將被刪除。 如果重映射函數本身引發(未檢查)異常,則
* 重新引導異常,並且當前映射保持不變。 重映射功能在計算過程中不應修改此映射。
*/
map.put("harry", null);
String present=map.computeIfPresent("bob", (k,v)->"on");
map.computeIfPresent("grant", (k,v)->null);
System.out.println(present);
map.forEach((k,v)->System.out.println(k+"-"+v));
注:1.以上3個方法都不應在計算過程中修改原映射,否則map的實現類將拋出ConcurrentModificationException.
2.注意jdk8中不要嘗試對ConcurrentHashMapz類中的computeIfAbsent方法使用遞歸,會導致一個bug,產生死循環.
/**
* 注意在ConcurrentHashMap中使用computeIfAbsent方法遞歸會導致一個bug,
* 使計算機進入一個死循環。實例代碼如下:
* resolved in jdk 9,在jdk 8避免以遞歸方式調用該方法
* 參考: https://bugs.openjdk.java.net/browse/JDK-8062841
* http://mp.weixin.qq.com/s/O6UmB7YDKIYtNvqCOjNwDQ
* */
// Map<String, Integer> curmap = new ConcurrentHashMap<>(16);
// curmap.computeIfAbsent(
// "AaAa",
// key -> {
// return curmap.computeIfAbsent(
// "BBBB",
// key2 -> 42);
// }
// );
4.default void forEach(BiConsumer<? super K, ? super V> action)
對此映射中的每個條目執行給定的操作,直到所有條目都被處理或操作引發異常。 除非實現類另有指定,否則按照進入設置迭代的順序執行操作(如果指定了迭代順序)。操作引發的異常被轉發給調用者。
map.forEach((k,v)->System.out.println(k+"-"+v));
5. default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
將每個條目的值替換爲對該條目調用給定函數的結果,直到所有條目都被處理或該函數拋出異常。 函數拋出的異常被轉發給調用方。
map.replaceAll((s1,s2)->{
if(s1.length()<=3) {
s2="";
}
return s2;
});
6. public void putAll(Map<? extends K, ? extends V> m)[複習舊的方法]
將指定地圖的所有映射覆制到此地圖。 這些映射將替換此映射對當前在指定映射中的任何鍵的任何映射。
//原api putAll--把map2放入map中,重複的key更新爲map2的value
Map<String,String> map2=new HashMap<>();
map2.put("rola", "8884");
map2.put("kann", "dew");
map.putAll(map2);
map.forEach((k,v)->System.out.println(k+"-"+v));
System.out.println(map2.size());
7.default V putIfAbsent(K key, V value) [舊]
如果指定的鍵尚未與某個值相關聯(或映射到 null
), null
其與給定值相關聯並返回 null
,否則返回當前值。
/**
* putIfAbsent與computeIfAbsent實現目的相同,區別是後者可使用lambda表達式
* 返回一個重映射函數,後者可以取代前者。
*/
map.putIfAbsent("bob", "in");
map.putIfAbsent("kyle", "48eww");
map.put("harry", "on");
map.forEach((k,v)->System.out.println(k+"-"+v));
System.out.println("5.----------------------------");
8.default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)
如果指定的鍵尚未與值相關聯或與null相關聯,則將其與給定的非空值相關聯。 否則,將關聯值替換爲給定重映射函數的結果,如果結果爲null
,則將其null
。如果重映射函數返回null
,則映射將被刪除。 如果重映射函數本身引發(未檢查)異常,則重新引導異常,並且當前映射保持不變。
/**
* 功能大部分與compute相同,不同之處在於BiFunction中apply的參數,入參爲
* oldValue、value,調用merge時根據兩個value進行邏輯處理並返回value。
*/
map.merge("bob", "in", (o,n)->n+o.toUpperCase());
map.merge("kann", "in", (o,n)->null);
map.merge("harry", "on", (o,n)->"ff");
map.forEach((k,v)->System.out.println(k+"-"+v));
9.default V getOrDefault(Object key, V defaultValue) 返回指定鍵映射到的值,如果此映射不包含鍵的映射,則返回 defaultValue 。
String getDefault1=map.getOrDefault("conner","not exists");
String getDefault2=map.getOrDefault("rola","not exists");
System.out.println(getDefault1);
System.out.println(getDefault2);