1. 程式人生 > 實用技巧 >Java中Set/HashSet的內部處理

Java中Set/HashSet的內部處理

眾所周知,集合是定義明確的不同物件的集合。集合的每個成員稱為集合的元素。因此,換句話說,我們可以說一個集合永遠不會包含重複的元素。但是如何在Java Set介面中實現的類(例如HashSet,LinkedHashSet,TreeSet等)實現這種唯一性。在本文中,我們將討論這種獨特性背後的隱藏真理。

HashSet如何在Java內部工作?


讓我們看看下面這個程式的輸出中有哪些元素是重複的。

// Java program to demonstrate 
// internal working of HashSet 

import java.util.HashSet; 

class Test 
{     
    
public static void main(String args[]) { // creating a HashSet HashSet hs = new HashSet(); // adding elements to hashset // using add() method boolean b1 = hs.add("Geeks"); boolean b2 = hs.add("GeeksforGeeks"); // adding duplicate element
boolean b3 = hs.add("Geeks"); // printing b1, b2, b3 System.out.println("b1 = "+b1); System.out.println("b2 = "+b2); System.out.println("b3 = "+b3); // printing all elements of hashset System.out.println(hs); } }

輸出:

b1 = true
b2 = true
b3 = false
[GeeksforGeeks, Geeks]

現在從輸出中可以清楚地看到,當我們嘗試使用add()方法新增相同的元素時,則返回false,元素未新增到hashset中,因為它已經存在。現在問題來了,怎麼做add()方法檢查集合是否已包含指定元素。如果我們仔細看看add()方法就會發現它定義了HashSet類中的預設建構函式。

// predefined HashSet class
public class HashSet
{
    // A HashMap object 
    private transient HashMap map;

    // A Dummy value(PRESENT) to associate with an Object in the Map
    private static final Object PRESENT = new Object();
    
    // default constructor of HashSet class
    // It creates a HashMap by calling 
    // default constructor of HashMap class
    public HashSet() {
        map = new HashMap<>();
    }

    // add method 
    // it calls put() method on map object
    // and then compares it's return value with null
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
 
    // Other methods in Hash Set
}

現在可以看到,每當我們建立一個HashSet時,它在內部建立一個HashMap,如果我們使用add()方法,它實際上呼叫了HashMap的put()方法,key為我們要設定的值,value為一個常量物件“PRESENT”,所以我們可知HashSet通過內部的HashMap儲存唯一的值。

那麼問題來了?HashMap的put()方法內部是怎麼實現的呢?

我們知道HashMap每個key都是獨一無二的,put(key,value)方法,則返回與鍵關聯的上一個值,或者null如果沒有鍵的對映。因此,在HashSet的add()方法中,我們使用null檢查map.put(key,value)方法的返回值。

  1. 如果map.put(key,value)返回null,則語句“map.put(e,PRESENT)==null”返回true,元素被新增到HashSet(內部HashMap)。
  2. 如果map.put(key,value)返回key對應的value,那麼語句“map.put(e,PRESENT)==null”將返回false,元素未新增到HashSet(內部HashMap)。