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/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

发表回复

登录后才能评论