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/zh-tw/n/140078.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
SJSQ的頭像SJSQ
上一篇 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

發表回復

登錄後才能評論