1. 程式人生 > >JAVA 8 併發增強 (4) ConcurrentHashMap批量操作

JAVA 8 併發增強 (4) ConcurrentHashMap批量操作

		/*
		 * java8為併發雜湊對映提供了批量操作資料操作,即使在其他執行緒同時操作對映時也可以安全的執行。
		 * 批量資料操作會遍歷對映並對匹配的元素進行操作。在批量操作過程中,不需要凍結對映的一個快照。除非你恰好知道在這段時間
		 * 內對映沒有被修改,否則你應該將結果看作是對映狀態的一個近似值。批量操作有三類
		 * a,search會對每個鍵或值應用一個函式,直到函式返回一個null的結果。然後search會終止並返回該函式的結果。
		 * b,reduce會通過提供的積累函式,將所有的鍵或指結合起來。c,forEach會對所有鍵或值對應一個函式。
		 * 使用這幾種操作時,需要指定一個並行閾值
		 * ,如果對映包含的元素數目超過了這個閾值,批量操作以並行的方式執行。如果希望批量操作資料在一個執行緒執行,
		 * 請使用Long.MAX_VALUE作為閾值。如果希望批量操作儘可能使用更多的執行緒,則應該使用1作為閾值。
		 */
		/*
		 * 比如希望找到第一個出現超過1000次的的單詞,我們需要搜尋鍵和值。 返回結果為第一個匹配的元素,或者沒有找到任何元素則返回null
		 */
		ConcurrentHashMap<String, Long> map = new ConcurrentHashMap<>();
		for (int i = 0; i < 1000; i++) {
			map.merge("a", 2L, Long::sum);//2000
			map.merge("b", 1L, Long::sum);//1000
		}
		String rs = map.search(1, (k, v) -> v > 1000 ? k : null);
		System.out.println(rs);
		/*
		 * foreach方法有兩種,第一種只是對每個對映資料項簡單的用一個消費者函式
		 * 第二種是額外接受一個轉換器函式,首先會應用此轉換器函式,然後再將結果傳遞給消費者函式、
		 * 轉換器函式可以被用作一個過濾器。當轉換器函式返回null時,值會被自動跳過
		 */
		map.forEach(1, (k, v) -> System.out.println(k + "->" + v));
		map.forEach(1, (k, v) -> k + "->" + v, System.out::println);
		map.forEach(1, (k, v) -> v > 1000 ? k + "->" + v : null, System.out::println);
		/*
		 *reduce操作將其輸入與一個累加函式結合起來。例如下面是計算所有值的總和
		 */
		Long sum = map.reduceValues(1, Long::sum);
		/*
		 *同forEach一樣,你也可以提供一個轉換器函式。比如計算長度最長的鍵
		 */
		Integer maxLength = map.reduceKeys(1, 
				String::length, //轉換器
				Integer::max);	//累加器
		System.out.println(maxLength);
		/*
		 * 轉換器函式可以作為一個過濾器,通過返回null來排除不想要的輸入。
		 * tips:如果對映是空的,或者所有的資料項都被過濾掉了,則reduce操作會返回null。如果只有一個元素,
		 * 那麼會返回它轉換後的值,並且不會應用累加函式。
		 */
		Long count = map.reduceValues(1, 
				v->v>1000?1L:null, //轉換器
				Long::sum);	//累加器
		System.out.println(count);
		/*
		 * 對於int,long,double型別的輸出,reduce操作提供了專門的方法,分別以ToInt,ToLong和ToDouble結尾。
		 * 你需要將輸入轉換為原始型別值,並指定一個預設值和累加器函式。當對映為空時返回預設值。
		 * tips:這幾個專門的方法與用於物件的方法行為不同,它們只會考慮一個元素。與返回轉換後的元素不同
		 * ,他們會對預設值進行累加,因此。預設值必須是累加器的中立元素。
		 */
		long sum2 = map.reduceValuesToLong(1, 
				Long::longValue, //轉換為原始型別
				0, 			//空對映的預設值 
				Long::sum);//原始型別累加器
	}