Java中put方法的使用

Java中的Map是一种非常常见的数据结构,其具有键值对的形式存储,通常用来存储一组相关的数据。而put方法是Map接口中的一种方法,该方法用来将一组键值对存储到Map中。在本篇文章中,我们将从多个方面介绍Java中put方法的使用。

一、put方法的基本使用

首先,我们来看一下put方法的基本使用:

    Map<String, String> map = new HashMap<>();
    map.put("name", "Tom");
    map.put("age", "18");

上述代码中,我们首先定义了一个Map实例,然后使用put方法将两组键值对存储到Map中。在这里,我们传入的是一个String类型的键和一个String类型的值。需要注意的是,在使用put方法的时候,如果Map中已经存在了这个键,则会用新的值替换旧的值。

二、put方法的返回值

除了将一组键值对存储到Map中之外,put方法还可以返回该键对应的旧值。例如:

    Map<String, String> map = new HashMap<>();
    map.put("name", "Tom");
    String oldValue = map.put("name", "Jerry");
    System.out.println(oldValue); // 输出Tom

上述代码中,我们首先使用put方法将键为”name”、值为”Tom”的键值对存储到Map中。接着,我们再次使用put方法,将键为”name”、值为”Jerry”的键值对存储到Map中。注意到在此过程中,Map中名为”name”的键已经存在,因此使用新的值”Jerry”替换掉了旧值”Tom”。而此时,put方法返回的值就是被替换掉的旧值”Tom”。

三、put方法的默认实现

Map接口中提供了多个不同的实现类,如HashMap、TreeMap、ConcurrentHashMap等。而在这些实现类中,put方法的具体实现也是不同的。下面我们来详细介绍一下HashMap和TreeMap中put方法的默认实现。

1. HashMap中put方法的默认实现

HashMap是一种散列表,它采用了”拉链法”来解决哈希冲突。下面是HashMap中put方法的默认实现:

    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            // 省略其他代码段
        }
        modCount++; // 记录Map中实际存储的键值对数量
        if (++size >= threshold) // 如果Map中的键值对数量超过了扩容阈值
            resize(); // 则进行扩容
        afterNodeInsertion(evict);
        return null;
    }

上述代码中,我们可以看到put方法的具体实现其实是调用了putVal方法,这个方法就是HashMap中put方法的具体实现。在这个方法中,我们可以看到,首先通过hash方法计算出了当前键对应的哈希值。接着,如果键对应的槽位没有被占用,就直接在该槽位中存储该键值对。否则,就需要对已经存在的键值对进行更新操作。最后,如果Map中的键值对数量超过了扩容阈值,就需要进行扩容操作。

2. TreeMap中put方法的默认实现

TreeMap是一种基于红黑树的映射。下面是TreeMap中put方法的默认实现:

    public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check
            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp; Entry<K,V> parent;
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
            Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }

上述代码中,我们可以看到put方法的具体实现是直接在TreeMap中新建一个Entry实例,并将其插入到红黑树中。在实现中,首先通过比较器(如果存在)或者键实现Comparable接口的compareTo方法(如果键没有指定比较器并且实现了Comparable接口)来判断当前键应该插入到红黑树的哪个位置。接着,如果节点已经存在,则用新的值替换旧的值,否则就将新节点插入到红黑树中。最后,如果摆动操作遵循红黑树插入的规则。

四、put方法的使用技巧

做到了上述的put方法的基本使用、返回值、默认实现,接下来我们将介绍一些使用技巧。

1. 使用putIfAbsent方法避免键的重复插入

在实际开发中,有时候需要向Map中插入一组键值对,但是如果键已经存在,则不插入。这个需求可以通过putIfAbsent方法来实现。例如:

    Map<String, String> map = new HashMap<>();
    map.put("name", "Tom");
    map.putIfAbsent("name", "Jerry");
    System.out.println(map.get("name")); // 输出Tom

上述代码中,由于”Tom”已经被存储为”name”键的值,因此使用putIfAbsent方法插入”Jerry”时会失败,不会对Map做出任何修改。在输出时,我们可以发现”name”键的值仍然为”Tom”。

2. 使用putAll方法批量插入键值对

如果需要将一个Map中的所有键值对都插入到另一个Map中,那么可以使用putAll方法。例如:

    Map<String, String> map1 = new HashMap<>();
    map1.put("name", "Tom");
    map1.put("age", "18");

    Map<String, String> map2 = new HashMap<>();
    map2.putAll(map1);

    System.out.println(map2.get("name")); // 输出Tom
    System.out.println(map2.get("age")); // 输出18

上述代码中,我们首先定义了map1,并向其中插入了两组键值对。接着,我们定义了一个空的map2,使用putAll方法将map1中的所有键值对都插入到map2中。最后,我们通过get方法检验了一下map2中存储的键值对是否正确。

3. 使用computeIfAbsent方法避免重复计算

在实际开发中,有时候需要根据键的值来计算一些数据,并将计算结果存储到Map中。如果键的值已经对应了一个存储的计算结果,那么就可以直接获取这个结果而不需要重复计算。这个需求可以使用computeIfAbsent方法来实现。例如:

    Map<String, Integer> map = new HashMap<>();
    map.put("count", 1);
    Integer result = map.computeIfAbsent("count", key -> computeCount(key));
    System.out.println(result); // 输出1

上述代码中,我们首先定义了一个名为count的键,对应的值为1。接着,我们使用computeIfAbsent方法来获取该键对应的计算结果。在这里,computeIfAbsent方法会首先检查名为count的键是否存在。由于count键已经被存储在map中,因此computeIfAbsent方法不会对该键进行计算,而是直接返回其对应的值1。最后,我们通过输出检查一下返回值是否为1。

五、小结

本文主要介绍了Java中Map接口中的put方法。我们从put方法的基本使用、返回值、默认实现和使用技巧四个方面进行了详细的介绍。除此之外,还结合具体的代码实现,帮助读者更加深入地了解Java中put方法的使用。

原创文章,作者:SJSQ,如若转载,请注明出处:https://www.506064.com/n/140078.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
SJSQSJSQ
上一篇 2024-10-04 00:23
下一篇 2024-10-04 00:23

相关推荐

  • 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

发表回复

登录后才能评论