0. References
In-depth Java Collection Learning series: the implementation principle of HashSet
1.HashSet Overview:
HashSet implements the set interface, which is supported by a hash table (actually a hashmap instance). It does not guarantee the set's iteration order, especially it does not guarantee that the order is constant. This class allows the use of NULL elements. Duplicate elements are not allowed in HashSet, because HashSet is implemented based on HashMap, and the elements in HashSet are stored on the HashMap key, and values in value are a unified private static final Object PRESENT = new Object ();. HashSet, like HashMap, is an array of linked lists.
The Add method in HashSet is called by the put () method in the underlying hashmap, and if you call put in HashMap, the first one will determine if the key exists and if key exists, modify the value if key does not exist to insert this key-value. In set, because value is not used, there is no argument for modifying the value, so adding an element to HashSet first determines if the element (that is, key) exists, and if there is no insertion, there is no duplicate value in the HashSet.
Implementation of 2.HashSet:
For HashSet, it is based on the HashMap implementation, hashset the underlying use HashMap to save all elements, more precisely, the elements in HashSet, just stored in the underlying HashMap key, and value using a static The final object identifier. Therefore, the implementation of HashSet is relatively simple, related hashset operations, basically directly call the underlying HASHMAP related methods to complete, hashset the source code is as follows:
PublicClass hashset<e>Extends abstractset<e>Implements Set<e>, Cloneable, java.io.serializable{StaticFinalLong Serialversionuid = -5024744406713321676l;//The underlying uses HashMap to hold all the elements in the hashset.PrivateTransient hashmap<e,object>Map//Defines a dummy object as the value of HashMap, which defines this object as static final.PrivateStaticFinal Object PRESENT =NewObject ();/*** The default parameterless constructor constructs an empty hashset. * * The actual underlying will initialize an empty HashMap and use the default initial capacity of 16 and load factor 0.75.*/PublicHashSet () {map =New hashmap<e,object>(); }/*** Constructs a new set containing the elements in the specified collection. * * The actual underlying uses the default load factor of 0.75 and is sufficient to contain the initial capacity of all elements in the specified * collection to create a hashmap. *@paramc The elements in this set will be stored in the collection.*/Public HashSet (COLLECTION<?Extends e>c) {map =New Hashmap<e,object> (Math.max (int) (C.size ()/.75f) + 1, 16)); AddAll (c); }/*** Constructs an empty hashset with the specified initialcapacity and loadfactor. * * The actual bottom layer constructs an empty hashmap with corresponding parameters. *@paramInitialcapacity initial capacity. *@paramLoadfactor load factor.*/Public HashSet (int initialcapacity,FloatLoadfactor) {map =New hashmap<e,object>(Initialcapacity, Loadfactor); }/*** Constructs an empty hashset with the specified initialcapacity. * * The actual bottom layer constructs an empty hashmap with corresponding parameters and load factor loadfactor of 0.75. *@paramInitialcapacity initial capacity.*/Public HashSet (Intinitialcapacity) {map =New hashmap<e,object>(initialcapacity); }/*** Constructs a new empty-link hash collection with the specified initialcapacity and loadfactor. * This constructor is for package access, not public, and is actually just a support for linkedhashset. * * The actual underlying will be implemented with an empty Linkedhashmap instance constructed with the specified parameters. *@paramInitialcapacity initial capacity. *@paramLoadfactor load factor. *@paramDummy tag.*/HashSet (int initialcapacity,Float Loadfactor,BooleanDummy) {map =New linkedhashmap<e,object>(Initialcapacity, Loadfactor); }/*** Returns an iterator that iterates over the elements in this set. The order of the returned elements is not specific. * * The underlying actual call to the underlying HashMap keyset to return all keys. * The elements in the hashset are visible only on the underlying HashMap key, * value uses a static final object identifier. *@returnThe iterator that iterates over the elements in this set.*/Public iterator<e>Iterator () {ReturnMap.keyset (). iterator (); }/*** Returns the number of elements in this set (capacity of Set). * * The number of elements in the set is obtained by actually calling HashMap's size () method to return the quantity of entry. *@returnThe number of elements in this set (capacity of Set).*/PublicIntSize () {ReturnMap.size (); }/*** Returns True if this set contains no elements. * * The underlying actual call to HashMap IsEmpty () determines whether the hashset is empty. *@returnReturns True if this set contains no elements.*/PublicBooleanIsEmpty () {ReturnMap.isempty (); }/*** Returns True if this set contains the specified element. * To be more exact, returns True when and only if this set contains an e element that satisfies (o==null. E==null:o.equals (e)) *. * * The underlying actual call to HashMap ContainsKey determines whether the specified key is included. *@paramo The element that has been tested in this set. *@returnReturns True if this set contains the specified element.*/PublicBooleanContains (Object o) {ReturnMap.containskey (o); }/*** If the specified element is not already contained in this set, the specified element is added. * More specifically, if this set does not contain an element E2 that satisfies (E==null. E2==null:e.equals (E2)) *, add the specified element e to this set. * If this set already contains the element, the call does not change the set and returns false. * * The underlying actually puts the element as key into the HashMap. * Because the HashMap put () method adds the Key-value pair, when the new HashMap in the entry of the key * is the same as the entry of the set (Hashcode () The return value is equal, and by equals compares true), * The value of the newly added entry will overwrite the value of the original entry, but the key will not change, so if you add an existing element to hashset, the newly added collection element will not be placed in the HashMap, and the original element does not change. This also satisfies the feature that the elements in set are not duplicated. *@paramE is added to the element in this set. *@returnReturns True if the set does not already contain the specified element.*/PublicBooleanAdd (e e) {Return Map.put (E, PRESENT) = =Null; }/*** If the specified element is present in this set, it is removed. * Rather, if this set contains an element e that satisfies (o==null. E==null:o.equals (e)), * it is removed. Returns True if this set already contains the element (or True if this set changes because of a call). (Once the call returns, the set no longer contains the element). * * The lower layer actually calls HashMap's Remove method to delete the specified entry. *@paramO An object that needs to be removed if it exists in this set. *@returnReturns True if the set contains the specified element.*/PublicBooleanRemove (Object o) {return Map.Remove (o) = =PRESENT; }/*** Removes all elements from this set. When this call returns, the set will be empty. * * The lower layer actually calls HashMap's clear method to empty all elements in the entry.*/PublicvoidClear () {map.clear ();}/** * Returns a shallow copy of this HashSet instance: The elements themselves are not copied. * * The underlying actually calls HashMap's Clone () method, gets the shallow copy of the HashMap, and sets it to HashSet. */Public Object Clone () { try {hashset<e> Newset = (hashset<e>) Super. Clone (); n Ewset.map = (hashmap<e, object>) Map.clone (); return Newset;} Catch (Clonenotsupportedexception e) { throw new internalerror (); }}}
3. Related notes:
- For the implementation of the relevant HashMap, please refer to my previous summary: in-depth Java Collection Learning Series: HASHMAP implementation principle.
- For objects saved in HashSet, be aware that their equals and hashcode methods are correctly overridden to guarantee the uniqueness of the objects that are placed.
Go: Drill down into the Java Collection Learning series: the implementation principle of HashSet