compute和putAbsent源碼分析及案例

compute源碼分析及案例

描述

校驗這個計算函數是否爲空,爲空拋出空指針異常。使用給定的key和獲取到的oldValue計算出一個新的值newValue。在新值爲空的前提下,如果舊的值不爲空,或者這個集合中包含這個key,則刪除這個key,並且返回null。在新值爲空的前提下,如果舊的值爲空,並且集合不包含這個key,什麼都不做,直接返回null。如果新值不爲空,添加這個新值和指定的key到集合,這裏可能是新增操作【新值不爲空,集合中不存在這個key】或者是替換操作【新值不爲空,集合中這個key,對應的val爲null】,返回這個新值。

參數

  • key:與指定值關聯的鍵
  • remappingFunction:計算值的函數

返回值

在新值爲空的前提下,如果舊的值不爲空,或者這個集合中包含這個key,則刪除這個key,並且返回null。在新值爲空的前提下,如果舊的值爲空,並且集合不包含這個key,什麼都不做,直接返回null。如果新值不爲空,添加這個新值和指定的key到集合,這裏可能是新增操作【新值不爲空,集合中不存在這個key】或者是替換操作【新值不爲空,集合中這個key,對應的val爲null】,返回這個新值。

源碼分析

default V compute(K key,
      BiFunction<? super K, ? super V, ? extends V> remappingFunction)
 
{
 // 校驗這個計算函數是否爲空,爲空拋出空指針異常
  Objects.requireNonNull(remappingFunction);
  // 使用給定的key獲取值,賦值給oldValue
 V oldValue = get(key);
  // 使用給定的key和獲取到的oldValue計算出一個新的值newValue
 V newValue = remappingFunction.apply(key, oldValue);
  // 判斷這個新的值是否爲空
 if (newValue == null) {
  // 如果在新值爲空的前提下,舊的值不爲空,或者這個集合中包含這個key
  if (oldValue != null || containsKey(key)) {
   // 刪除這個key,並且返回null
   remove(key);
   return null;
  } else {
   // 如果在新值爲空的前提下,舊的值爲空,並且集合不包含這個key,什麼都不做,直接返回null
   return null;
  }
 } else {
  // 新值不爲空,添加這個新值和指定的key到集合
    // 這裏可能是新增操作【新值不爲空,集合中不存在這個key】或者是替換操作【新值不爲空,集合中這個key,對應的val爲null】
  put(key, newValue);
    // 返回這個新值
  return newValue;
 }
}

案例

@Test
public void test_compute_01(){
 Map<String, String> map = new HashMap<>();
 String key = "aaa";
 String msg = "hahh";
 // key對應的val不存在,會將key和msg添加到集合中,並返回這個msg,這個執行的是新增操作
 String compute = map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg));
 System.out.println(compute);
 map.forEach((k, v) -> System.out.println("=======key: " + k + "========v: " + v));
}

@Test
public void test_compute_01_val_null(){
 Map<String, String> map = new HashMap<>();
 String key = "aaa";
 String msg = null;
 // key對應的val不存在,會將key和msg添加到集合中,並返回這個msg
 String compute = map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg));
 System.out.println(compute);
 map.forEach((k, v) -> System.out.println("=======key: " + k + "========v: " + v));
}

@Test
public void test_compute_02(){
 Map<String, String> map = new HashMap<>();
 String key = "aaa";
 String msg = "hahh";
 map.put(key, "uuu");
 // key對應的val存在,並且不爲空,使用concat函數在原有的val後面追加新值,並返回追加後的新值,然後添加到集合中
 String compute = map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg));
 System.out.println(compute);
 map.forEach((k, v) -> System.out.println("=======key: " + k + "========v: " + v));
}

@Test
public void test_compute_03(){
 //java8 實現計算功能統計字符串出現次數
 Map<String, Integer> map = new HashMap<>();
 List<String> source = Arrays.asList("hello""world""hello""welcome""hello""hello""welcome""world");
 source.forEach(s -> map.compute(s, (k, v) -> Objects.isNull(v) ? 1 : v + 1));
 System.out.println(map);
}

putIfAbsent源碼分析及案例

描述

根據key獲取舊的val,如果舊的值不爲空,返回舊的val,如果舊的val爲空【這個集合要支持val爲空】,返回新添加的val,這個新添加的val可能爲null。

參數

  • Key:與指定值關聯的鍵
  • value:與指定鍵關聯的值

返回值

如果舊的值不爲空,返回舊的val,如果舊的val爲空【這個集合要支持val爲空】,返回新添加的val,這個新添加的val可能爲null。

源碼分析

default V putIfAbsent(K key, V value) {
  // 根據key獲取舊的val
 V v = get(key);
 // 判斷舊的val是否爲空
 if (v == null) {
   // 舊的val爲空,將這個key和value添加到集合中
  v = put(key, value);
 }
 // 如果舊的值不爲空,返回舊的val,如果舊的val爲空,返回新添加的val,這個新添加的val可能爲null
 return v;
}

案例

@Test
public void test_putAbsent_01(){
 // HashMap是允許鍵和值爲null的
 Map<String, String> map = new HashMap<>();
 // 驗證key和val鍵值對在集合中都不存在
 map.putIfAbsent("aaa""hhh");
 map.forEach((k, v) -> System.out.println("===key: " + k + "===value: " + v));
}

@Test
public void test_putAbsent_02(){
 Map<String, String> map = new HashMap<>();
 // HashMap是允許鍵和值爲null的
 map.put("aaa"null);
 // 驗證key和val都存在集合中,但是key對應的val爲null
 map.putIfAbsent("aaa""bbb");
 map.forEach((k, v) -> System.out.println("===key: " + k + "===value: " + v));
}

@Test
public void test_putAbsent_03(){
 Map<String, String> map = new HashMap<>();
 map.put("aaa""bbb");
 // 驗證key和val都存在集合中,並且key對應的val不爲null
 map.putIfAbsent("aaa""ccc");
 map.forEach((k, v) -> System.out.println("===key: " + k + "===value: " + v));
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章