Map的常用方法 案例1 場景:一張建行用戶體驗金信息大表(百萬級別),裡面存在一個欄位對多條數據,需要統計某個欄位的多條數據累加值以供於別的服務調用。 優化前解決:直接查出來一個大list給到另一個服務,再另外一個服務里有笛卡爾積算出累加值(笛卡爾積後得到jvm需運算56億次),程式直接接近崩潰, ...
Map的常用方法
案例1
場景:一張建行用戶體驗金信息大表(百萬級別),裡面存在一個欄位對多條數據,需要統計某個欄位的多條數據累加值以供於別的服務調用。
優化前解決:直接查出來一個大list給到另一個服務,再另外一個服務里有笛卡爾積算出累加值(笛卡爾積後得到jvm需運算56億次),程式直接接近崩潰,故需優化。
優化思路:首先由於該表是一張大表,所以我們不能直接把這百萬級別轟到記憶體中(不然會OOM),我們先分組取出,分組迭代使用Map的Merge方法(源碼如下),該方法接收了三個參數,一個是Key,一個是value,一個是remappingFunction,簡單理解,如果給定的key不存在,它就變成了 put(key, value) ;但是,如果 key 已經存在一些值,我們 remappingFunction 可以選擇合併的方式,然後將合併得到的 newValue 賦值給原先的 key。
// 源碼如下
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if (newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}
案例2
場景:邏輯需要移除map里特定的key和value元素
優化前解決:遍歷找出對應條件,程式效率不高,很多無效判斷
優化思路:使用map jdk1.8新增方法一步解決,remove方法,該方法有兩個入參,一個是key,一個是value。基本理解,僅當指定的 key 關聯到指定的 value 時,才刪除指定的項,刪除成功返回 true。
// 源碼如下
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;
}
Map的另外一些新增方法示例
// 原有的Put方法,是當Key存在時則替換;而putIfAbsent方法,則是當存在Key忽略Put操作不替換
map.putIfAbsent("K1001", "K1001-1");
// 如果Key存在,則將函數的運算結果作為這個Key對應的Value的新值Put進去
map.computeIfPresent("K1001", (k, v) -> k + v);
// 如果Map中不存這個Key對應個的鍵值對,則Put這個Key和將Key帶入函數運算後的結果為Value的鍵值對;如果Key存在,則忽略Put操作
map.computeIfAbsent("K1002", k -> k);
// 只有當Map中鍵值對同時等於參數Key和Value時才執行刪除
map.remove("K1002", "K1002");
// 從Map中獲取指定Key的Value的值,如果不存在則返回指定的預設值
String vle = map.getOrDefault("K1002", "V1002");
System.out.println(vle);
// 遍歷 forEach
map.forEach((k, v) -> System.out.println(k + " --> " + v));