Java中Set/HashSet的內部處理
阿新 • • 發佈:2020-09-12
眾所周知,集合是定義明確的不同物件的集合。集合的每個成員稱為集合的元素。因此,換句話說,我們可以說一個集合永遠不會包含重複的元素。但是如何在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 elementboolean 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)方法的返回值。
- 如果map.put(key,value)返回null,則語句“map.put(e,PRESENT)==null”返回true,元素被新增到HashSet(內部HashMap)。
- 如果map.put(key,value)返回key對應的value,那麼語句“map.put(e,PRESENT)==null”將返回false,元素未新增到HashSet(內部HashMap)。