Java中的map.computeIfAbsent方法使用詳解

在日常的 Java 開發中,經常需要使用 Map 來存儲一些鍵值對數據,其中 ConcurrentHashMap 是常用的線程安全 ConcurrentHashMap。但是,對於 ConcurrentHashMap 的線程安全來說,開發者還需要考慮 ConcurrentHashMap 中鍵值對數據的並發訪問問題。在實際的開發過程中,經常需要對鍵值對進行檢查和處理,這時需要使用到 Map 中的 computeIfAbsent 方法。

一、概述

Map 中的 computeIfAbsent 方法,可以用來獲取指定 key 的 value 值。如果該 key 不存在,則使用 lambda 表達式計算一個新的 value 值並保存到 Map 中,然後返回該新的 value 值。當該 key 對應的 value 值不為 null 時,可以使用 BiFunction 參數進行新的計算或返回舊值。

二、用法說明

computeIfAbsent 方法的語法如下所示:

default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)

對於 ConcurrentHashMap 來說,computeIfAbsent 方法對於多個線程同時對一個 key 進行操作時,只會有一個線程對該 key 進行操作,其他線程會等待該線程處理完成後返回結果。另外,如果 mappingFunction 函數返回 null,則不會將 key 值和 null 的結果插入 Map 中。

computeIfAbsent 方法的具體使用如下所示:

Map<String, String> map = new ConcurrentHashMap<>();
map.computeIfAbsent(key, k -> {
    // 計算並返回 value 值
});

三、示例

示例1:獲取指定 key 對應的 value 值

下面是一個示例,演示如何獲取指定 key 的 value 值(key 不存在時返回新的 value 值):

Map<String, String> map = new ConcurrentHashMap<>();
map.computeIfAbsent("key1", k -> {
    System.out.println(k + " is not exist");
    return "value1";
});
System.out.println("value of key1 is " + map.get("key1"));

輸出結果如下所示:

key1 is not exist
value of key1 is value1

在上述示例中,由於鍵值對 “key1” 不存在,lambda 表達式會創建一個新的 value 值並保存到 ConcurrentHashMap 中,然後返回該新的 value 值。輸出結果中,第一行為執行 lambda 表達式創建新的 value 值;第二行為輸出獲取的 value 值。

示例2:對指定 key 對應的 value 值進行計算

下面是一個示例,演示如何對指定 key 對應的 value 值進行計算(key 不存在時創建新的 value 值):

Map<String, Integer> map = new ConcurrentHashMap<>();
map.computeIfAbsent("key1", k -> 1);
map.computeIfAbsent("key1", k -> 2 + map.get(k));
System.out.println(map.get("key1"));

輸出結果如下所示:

3

在上述示例中,由於鍵值對 “key1” 不存在,第一個 computeIfAbsent 方法會創建一個新的 value 值 1 並保存到 ConcurrentHashMap 中。第二個 computeIfAbsent 方法會對 key 對應的 value 值進行計算,根據 computeIfAbsent 方法的語法,第一個參數是 key,第二個參數是對於該 key 已經存在的 value 值做的新的計算或返回舊值的 BiFunction 函數,所以第二個 computeIfAbsent 方法的 lambda 表達式中訪問了 “key1” 對應的舊值 1,並把舊值加上 2 返回了一個新的值 3,然後將計算得到的新值替換舊值保存到 ConcurrentHashMap 中。

示例3:處理 key 不存在時異常

下面是一個示例,演示如何處理 key 不存在時的異常:

Map<String, String> map = new ConcurrentHashMap<>();
try {
    System.out.println(map.computeIfAbsent(null, k -> "value1"));
} catch (Exception e) {
    e.printStackTrace();
}

輸出結果如下所示:

java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
    at cn.ljh.lockdemo.HashTableDemo.lambda$testComputeIfAbsentException$3(HashTableDemo.java:122)
    at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1003)
    at cn.ljh.lockdemo.HashTableDemo.testComputeIfAbsentException(HashTableDemo.java:120)

在上述示例中,由於 key 為 null,所以在執行 computeIfAbsent 方法時會拋出 NullPointerException 異常。如果需要處理這個異常,可以在代碼中使用 try-catch 塊捕獲異常並進行處理。

四、總結

本文主要講解了 Map 中的 computeIfAbsent 方法的使用方法和示例。在實際的 Java 開發中,開發者經常需要對鍵值對進行檢查和處理,使用 computeIfAbsent 方法可以更加方便地對鍵值對進行操作,在多線程環境下保證了並發訪問數據的正確性,使得開發更加高效。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/289369.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-24 03:02
下一篇 2024-12-24 03:02

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • ArcGIS更改標註位置為中心的方法

    本篇文章將從多個方面詳細闡述如何在ArcGIS中更改標註位置為中心。讓我們一步步來看。 一、禁止標註智能調整 在ArcMap中設置標註智能調整可以自動將標註位置調整到最佳顯示位置。…

    編程 2025-04-29
  • 解決.net 6.0運行閃退的方法

    如果你正在使用.net 6.0開發應用程序,可能會遇到程序閃退的情況。這篇文章將從多個方面為你解決這個問題。 一、代碼問題 代碼問題是導致.net 6.0程序閃退的主要原因之一。首…

    編程 2025-04-29
  • Python創建分配內存的方法

    在python中,我們常常需要創建並分配內存來存儲數據。不同的類型和數據結構可能需要不同的方法來分配內存。本文將從多個方面介紹Python創建分配內存的方法,包括列表、元組、字典、…

    編程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一個類的構造函數,在創建對象時被調用。在本篇文章中,我們將從多個方面詳細討論init方法的作用,使用方法以及注意點。 一、定義init方法 在Pyth…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發佈。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29

發表回復

登錄後才能評論