Java computeIfAbsent 方法詳解

一、Java 的 ConcurrentHashMap

在討論 computeIfAbsent 方法之前,我們需要先了解一下 Java 中的 ConcurrentHashMap。ConcurrentHashMap 是一個線程安全的哈希表,實現了 Map 介面。它被設計用來支持高並發,因為它可以在多個線程同時訪問一個或多個桶(buckets)而不會出現數據不一致的情況。

ConcurrentHashMap 的實現方式與 HashMap 不同。它將哈希表分為許多桶,並且每個桶都是一個單獨的鎖。當一個線程訪問哈希表的某個桶時,只有這個桶被鎖定,其他線程可以同時訪問其他桶。這使得 ConcurrentHashMap 可以支持高並發。

ConcurrentHashMap map = new ConcurrentHashMap();

二、computeIfAbsent 方法的定義和作用

1、什麼是 computeIfAbsent 方法

computeIfAbsent 方法是 ConcurrentHashMap 中的一個方法。它的作用是:如果指定的 key 在 map 中不存在,那麼就使用指定的函數計算它的值,並將 key-value 對添加到 map 中。如果指定的 key 已經存在於 map 中,則返回其對應的 value 值。

2、computeIfAbsent 方法的定義

computeIfAbsent 方法的定義如下:

default V computeIfAbsent(K key, Function mappingFunction)

其中,參數 key 表示要操作的 key,參數 mappingFunction 表示計算 key 對應的 value 的函數,它的類型為 Function。

3、computeIfAbsent 方法的作用

當調用 computeIfAbsent 方法時,ConcurrentHashMap 會檢查指定的 key 是否已經存在於哈希表中。如果 key 已經存在,則將與之關聯的 value 返回。如果 key 不存在,則傳遞給 computeIfAbsent 方法的 mappingFunction 函數將被調用。該函數將 key 作為參數,返回一個新的 value。新的 key-value 對將自動添加到 ConcurrentHashMap 中,並且 computeIfAbsent 會返回新的 value。

三、computeIfAbsent 方法的使用

下面我們來看一個 computeIfAbsent 方法的使用示例。代碼中使用了 ConcurrentHashMap,裡面存放了若干個 Fruit 對象,每個 Fruit 對象包含了水果的名稱和價格。

import java.util.concurrent.ConcurrentHashMap;

class Fruit {
    private String name;
    private int price;

    public Fruit(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public int getPrice() {
        return price;
    }
}

public class ConcurrentHashMapDemo {

    public static void main(String[] args) {
        ConcurrentHashMap map = new ConcurrentHashMap();

        // 果盤裡沒有蘋果,就添加一個蘋果對象
        Fruit apple = map.computeIfAbsent("apple", key -> new Fruit("apple", 2));
        System.out.println(apple.getName() + ": " + apple.getPrice());

        // 果盤裡已經有蘋果了,就不需要再新建一個蘋果對象了
        Fruit anotherApple = map.computeIfAbsent("apple", key -> new Fruit("another apple", 3));
        System.out.println(anotherApple.getName() + ": " + anotherApple.getPrice());
    }
}

運行上述代碼,輸出結果如下:

apple: 2
apple: 2

我們可以看到,第一次調用 computeIfAbsent 方法時,果盤裡沒有蘋果,因此新建了一個名為 “apple” 的蘋果對象,並將其添加到 map 中。第二次調用 computeIfAbsent 方法時,果盤裡已經有了一個名為 “apple” 的蘋果對象,因此第二個參數中的 lambda 表達式不會被執行,而是直接返回 map 中已有的蘋果對象。

四、computeIfAbsent 方法的優點

使用 computeIfAbsent 方法可以省略掉一些 if 判斷和 synchronized 同步,因為 computeIfAbsent 已經保證了線程安全。此外,在使用 computeIfAbsent 方法時,我們可以像示例代碼中一樣使用 lambda 表達式,使代碼更加簡潔易讀。

五、小結

在 Java 中,ConcurrentHashMap 是一個支持高並發的線程安全 Map。它提供了許多常用的方法,其中包括 computeIfAbsent 方法。使用 computeIfAbsent 方法可以有效地處理多線程並發的問題,同時也能使代碼更加簡潔易讀。在實際開發中,我們應該充分發揮 ConcurrentHashMap 的優勢,使用 computeIfAbsent 方法來實現線程安全的數據處理。

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

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

相關推薦

  • Java JsonPath 效率優化指南

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

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

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

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

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

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

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

    編程 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

發表回復

登錄後才能評論