The realization of HashSet
For HashSet, it is based on HASHMAP implementation, HashSet the bottom of the HashMap to save all the elements, so HashSet implementation is relatively simple, view the source code of HashSet, you can see the following code:
Java code
- Public class Hashset<e>
- extends Abstractset<e>
- implements Set<e>, cloneable, Java.io.Serializable
- {
- //Use HashMap key to save all elements in HashSet
- private transient hashmap<e,object> map;
- //Define a dummy object as the value of HashMap
- private Static final Object PRESENT = new Object ();
- ...
- //Initialize HashSet, the underlying initializes a HashMap
- Public HashSet ()
- {
- Map = new hashmap<e,object> ();
- }
- //Create HashSet with the specified initialcapacity, Loadfactor
- //actually is to create the HASHMAP with corresponding parameters
- Public HashSet (int initialcapacity, float loadfactor)
- {
- Map = New Hashmap<e,object> (initialcapacity, loadfactor);
- }
- Public HashSet (int initialcapacity)
- {
- Map = new hashmap<e,object> (initialcapacity);
- }
- HashSet (int initialcapacity, float loadfactor, boolean dummy)
- {
- Map = new linkedhashmap<e,object> (initialcapacity
- , Loadfactor);
- }
- //Call map's keySet to return all keys
- Public iterator<e> Iterator ()
- {
- return Map.keyset (). iterator ();
- }
- ///Call HashMap the size () method returns the number of Entry, and the number of elements in the Set
- public int size ()
- {
- return map.size ();
- }
- //Call HashMap's IsEmpty () to determine if the HashSet is empty,
- //When the HashMap is empty, the corresponding HashSet is also empty
- Public Boolean isEmpty ()
- {
- return Map.isempty ();
- }
- //Call HashMap ContainsKey to determine if the specified key is included
- all the elements of//hashset are saved by the HASHMAP key .
- Public Boolean contains (Object o)
- {
- return Map.containskey (o);
- }
- //Put the specified element in HashSet, that is, put the element as a key HashMap
- Public Boolean add (E e)
- {
- return Map.put (E, PRESENT) = = null;
- }
- //Call the HashMap Remove method to delete the specified Entry, and then delete the corresponding element in the HashSet
- Public boolean remove (Object o)
- {
- return Map.Remove (o) ==present;
- }
- //The Clear method of calling Map clears all Entry and clears all elements in HashSet
- public void Clear ()
- {
- Map.clear ();
- }
- ...
- }
As can be seen from the above source program, the implementation of HashSet is very simple, it just encapsulates a HashMap object to store all the collection elements, all the collection elements put into HashSet are actually saved by the key of HashMap, while the HASHMAP value is stored A PRESENT, which is a static object.
Most of the methods of HashSet are implemented by invoking the HashMap method, so HashSet and HashMap two sets are essentially the same in their implementations.
After mastering the above theoretical knowledge, take a look at an example program and test whether you really mastered the functions of the HashMap and HashSet collections.
Java code
- class Name
- {
- private String first;
- private String last;
- Public Name (string First, string last)
- {
- This.first = First;
- this.last = last;
- }
- public Boolean equals (Object o)
- {
- if (this= = O)
- {
- return true;
- }
- if (o.getclass () = = Name. Class)
- {
- Name n = (name) o;
- return N.first.equals (first)
- && n.last.equals (last);
- }
- return false;
- }
- }
- Public class Hashsettest
- {
- public static void Main (string[] args)
- {
- set<name> s = new hashset<name> ();
- S.add (new Name ("abc", "123"));
- System.out.println (
- S.contains (new Name ("abc", "123")));
- }
- }
After adding a new name ("abc", "123") object to HashSet in the above program, it is immediately determined by the program that the HashSet contains a new name ("abc", "123") object. Coarse looks, it is easy to assume that the program will output true.
Actually running the above program will see the program output false, this is because HashSet judge two objects equal to the standard in addition to the Equals () method is required to return true, but also requires two objects hashcode () return values equal. The above program does not override the name class's Hashcode () method, the Hashcode () return value of the two name objects is not the same, so HashSet treats them as 2 objects, so the program returns FALSE.
Thus, it is important to override the Equals (Object obj) method and the Hashcode () method of this class when we try to treat the object of a class as a HashMap key, or try to save the object of this class in HashSet. And the return values of the two methods must be consistent: when the two hashcode () return values of the class are identical, they should also return true through the Equals () method. In general, all key attributes that participate in the calculation of the hashcode () return value should be used as the criteria for the Equals () comparison.
The following program correctly rewrites the hashcode () and Equals () methods of the Name class, with the following procedures:
Java code
- Class Name
- {
- private String first;
- private String last;
- Public Name (string First, string last)
- {
- This.first = First;
- this.last = last;
- }
- //Determine if two Name is equal according to first
- public Boolean equals (Object o)
- {
- if (this= = O)
- {
- return true;
- }
- if (o.getclass () = = Name. Class)
- {
- Name n = (name) o;
- return n.first.equals (first);
- }
- return false;
- }
- //Hashcode () return value of Name object based on first calculation
- public int hashcode ()
- {
- return First.hashcode ();
- }
- Public String toString ()
- {
- return "name[first=" + First + ", last=" + Last + "]";
- }
- }
- public class HashSetTest2
- {
- public static void Main (string[] args)
- {
- hashset<name> set = new hashset<name> ();
- Set.add (new Name ("abc", "123"));
- Set.add (new Name ("abc", "456"));
- SYSTEM.OUT.PRINTLN (set);
- }
- }
The above program provides a name class that overrides the Equals () and toString () two methods, both of which are judged by the first instance variable of the name class, and when the first instance variable of the two name object is equal, the two N The Hashcode () return value of the Ame object is also the same, and true is also returned by the Equals () comparison.
The main method of the program first adds the first name object to the HashSet, the name object is named "ABC", and then the program tries again to add a Name object "ABC" to the HashSet, it is clear that the new Na The Me object is added to the HashSet because the first of the name object you are trying to add is also "ABC", and HashSet will determine that the new name object here is the same as the original name object and therefore cannot be added, and the program will look at the output set collection at ① code. To the collection contains only one name object, which is the first name object that is "123".
HashSet in Java (GO)