Jdk 1.8-Map接口新方法-201804

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);




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章