Document directory
- 0. References
- 3. Instructions:
0. References
Go deep into Java Collection Learning Series: 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 iteration sequence; in particular, it does not ensure that the sequence remains unchanged. This class allows the use of null elements. Duplicate elements are not allowed in hashset. This is because hashset is implemented based on hashmap. All elements in hashset are stored on the key of hashmap, and the values in values are unified.Private Static final object present = new object ();. Like hashmap, hashset is an array that stores linked lists.
The add method in hashset calls the put () method in the underlying hashmap. If the put method is called in hashmap, the system first checks whether the key exists. If the key exists, the value is modified, if the key does not exist, insert this key-value. In the set, because the value is useless, there is no argument for modifying the value. Therefore, to add an element to the hashset, first determine whether the element (that is, the key) exists, if this insert does not exist, if there is no insert, there will be no duplicate values in the hashset.
2. Implementation of hashset:
For a hashset, it is implemented based on hashmap. The hashset uses hashmap at the underlying layer to store all elements. More specifically, the elements in the hashset are only stored on the key of the underlying hashmap, value uses a static final object identifier. Therefore, the implementation of hashset is relatively simple. The operations related to hashset are basically completed by directly calling the related methods of the underlying hashmap. The source code of hashset is as follows:
View code
Public class hashset <E> extends abstractset <E> implements set <E>, cloneable, Java. io. serializable {static final long serialversionuid =-5024744406713321676l; // use hashmap at the underlying layer to save all elements in the hashset. Private transient hashmap <E, Object> map; // defines a virtual object as the value of hashmap, which is defined as static final. Private Static final object present = new object ();/*** the default no-argument constructor constructs an empty hashset. ** An empty hashmap is initialized at the underlying layer, and the default initial capacity is 16 and the load factor is 0.75. */Public hashset () {map = new hashmap <E, Object> () ;}/ *** constructs a new set containing elements in the specified collection. ** The actual underlying layer uses the default load factor 0.75 and is sufficient to contain the initial capacity of all elements in the specified * Collection to create a hashmap. * @ Param C the elements in it will be stored in the collection in this set. */Public hashset (collection <? Extends E> C) {map = new hashmap <E, Object> (math. max (INT) (C. size ()/. 75f) + 1, 16); addall (c) ;}/ *** construct an empty hashset with the specified initialcapacity and loadfactor. ** The actual underlying layer constructs an empty hashmap with corresponding parameters. * @ Param initialcapacity initial capacity. * @ Param loadfactor: load factor. */Public hashset (INT initialcapacity, float loadfactor) {map = new hashmap <E, Object> (initialcapacity, loadfactor );} /*** construct an empty hashset with the specified initialcapacity. ** At the underlying layer, an empty hashmap is constructed based on the corresponding parameter and loading Factor loadfactor 0.75. * @ Param initialcapacity initial capacity. */Public hashset (INT initialcapacity) {map = new hashmap <E, Object> (initialcapacity );} /*** construct a new empty link hash set with the specified initialcapacity and loadfactor. * This constructor is the package access permission and is not disclosed to the public. It is actually only supported by javashashset. ** At the underlying layer, an empty linkedhashmap instance is constructed with the specified parameters. * @ Param initialcapacity initial capacity. * @ Param loadfactor: load factor. * @ Param dummy mark. */Hashset (INT initialcapacity, float loadfactor, Boolean dummy) {map = new linkedhashmap <E, Object> (initialcapacity, loadfactor );} /*** return the iterator for performing iteration on the elements in this set. The returned element sequence is not specific. ** The underlying layer actually calls the keyset of the underlying hashmap to return all keys. * The elements in the hashset are only stored on the key of the underlying hashmap. * value uses a static final object identifier. * @ Return iterator that iterates on the elements in this set. */Public iterator <E> iterator () {return map. keyset (). iterator () ;}/ *** return the number of elements in the Set (set capacity ). ** The number of entries returned by actually calling the size () method of hashmap at the underlying layer gets the number of elements in the set. * @ Return the number of elements in this set (set capacity ). */Public int size () {return map. Size () ;}/ *** returns true if this set does not contain any element. ** The underlying layer actually calls the isempty () of hashmap to determine whether the hashset is empty. * @ Return if this set does not contain any elements, true is returned. */Public Boolean isempty () {return map. isempty ();}/*** returns true if the set contains the specified element. * More specifically, when and only when this set contains a satisfied (O = NULL? E = NULL: O. Equals (E) *, returns true. ** The underlying layer actually calls the hashinskey of hashmap to determine whether it contains the specified key. * @ Param o There Is A tested element in this set. * @ Return if this set contains the specified element, true is returned. */Public Boolean contains (Object O) {return map. containskey (o);}/*** if this set does not contain the specified element, add the specified element. * More specifically, if this set does not contain meet (E = NULL? E2 = NULL: E. Equals (E2) *, add the specified Element E to this set. * If this set already contains this element, the call does not change the set and returns false. ** The underlying layer actually puts this element as a key into hashmap. * When a key-value pair is added to the put () method of hashmap, when the key * in the newly added entry of hashmap is the same as the key of the original entry in the Set (hashcode () returns the same value, returns true through equals comparison). * The value of the newly added entry will overwrite the value of the original entry, but the key will not change, * If an existing element is added to a hashset, the newly added collection element will not be placed in the hashmap. * The original element will not change, this satisfies the non-repetition of elements in the set. * @ Param E: The elements added to this set. * @ Return returns true if the set does not contain the specified element. */Public Boolean add (E) {return map. put (E, present) = NULL;}/*** if the specified element exists in this set, remove it. * To be more precise, if this set contains a satisfied (O = NULL? E = NULL: O. Equals (E) Element E, * remove it. If this set already contains this element, true * is returned (or, if this set is changed due to call, true is returned ). (This set no longer contains this element once it is returned ). ** The underlying layer actually calls the Remove Method of hashmap to delete the specified entry. * @ Param o the object to be removed if it exists in this set. * @ Return if set contains the specified element, true is returned. */Public Boolean remove (Object O) {return map. Remove (o) = present;}/*** remove all elements from this set. After this call is returned, the set is empty. ** The bottom layer actually calls the clear method of hashmap to clear all elements in the entry. */Public void clear () {map. Clear () ;}/ *** returns a superficial copy of this hashset instance: these elements are not copied. ** The underlying layer actually calls the clone () method of hashmap to obtain the superficial copy of hashmap and set it to hashset. */Public object clone () {try {hashset <E> newset = (hashset <E>) super. clone (); newset. map = (hashmap <E, Object>) map. clone (); Return newset;} catch (clonenotsupportedexception e) {Throw new internalerror ();}}}
3. Instructions:
- For more information about the implementation principles of hashmap, see my previous summary: go deep into the Java Collection Learning Series: Implementation Principles of hashmap.
- For objects stored in a hashset, note that the equals and hashcode methods are correctly rewritten to ensure the uniqueness of the put objects.