I. Introduction of HashSet
HashSet is a typical implementation of the set interface, which stores the elements in the collection according to the hash algorithm, and has good access and lookup performance. Mainly has the following characteristics:
- The set iteration order is not guaranteed
- HashSet is not synchronous, and if multiple threads are accessing a hashset at the same time, they are guaranteed to be synchronized by code
- The collection element value can be null
When an element is deposited into the HashSet collection, HashSet calls the object's Hashcode () method to get the Hashcode value of the object, and then determines where the object is stored in hashset based on that value. In a hash set, it is not possible to store two equal elements at the same time, while the criterion for judging two elements is equal, and two objects are compared by the Equals method and the return value of the Hashcode method of two objects is equal.
The following examples illustrate the above features:
public class person{ String name; int age; Public person (String Name,int age) { this.name=name; this.age=age; } Public String getName () { return name; } public void SetName (String name) { this.name = name; } public int getage () { return age; } public void Setage (int.) { this.age = age; } Returns true if the object's name and name are the same as public Boolean equals (Object obj) { if (obj==null) return false; if ((this.name.equals (person) obj. Name) && this.age== (person) obj) return true; else return false; } }
At this point, add two person object instances of the same name and age to HashSet:
public class hashsetdemo{public static void Main (string[] args) { hashset<person> hs = new HashSet <> (); Person P1=new person ("Xujian"); Person P2=new person ("Xujian"); Hs.add (p1); Hs.add (p2); for (person P:hs) { System.out.println (p.name+ "---" +p.age); } }}
As can be seen, the hashset contains two person objects with the same name and age.
Next we rewrite the Hashcode method of the person class so that it returns the same hashcode.
public class person{ String name; int age; Public person (String Name,int age) { this.name=name; this.age=age; } Public String getName () { return name; } public void SetName (String name) { this.name = name; } public int getage () { return age; } public void Setage (int.) { this.age = age; } public int hashcode () { //TODO auto-generated method stub return 1; } Returns true if the object's name and name are the same as public Boolean equals (Object obj) { if (obj==null) return false; if ((this.name.equals (person) obj. Name) && this.age== (person) obj) return true; else return false; } }
Once again, adding an element to the hashset operation, you will find that HashSet only saved one at this time.
The slots for each of the hashset elements are often referred to as "buckets", and if multiple elements are hashcode the same, but returning false by the Equals method, you need to store multiple elements on a bucket.
Ii. hashset Source Code Analysis 1, the structure function
The bottom of the hashset is actually implemented by HashMap. Its four constructors correspond to corresponding HashMap respectively.
Constructs a new, empty HashSet, the default initial capacity of its underlying HASHMAP instance is 16, the load factor is 0.75 public HashSet () { map = new hashmap<> (); } //Constructs a new set public HashSet (collection<? extends e> c) that contains the elements in the specified collection { map = new HashMap <> (Math.max ((int) (C.size ()/.75f) + 1, +)); AddAll (c); } Constructs a new empty set whose underlying HASHMAP instance has the specified initial capacity and the specified load factor public HashSet (int initialcapacity, float loadfactor) { map = New Hashmap<> (initialcapacity, loadfactor); } Constructs a new empty set whose underlying HASHMAP instance has the specified initial capacity and the default load factor 0.75 public HashSet (int initialcapacity) { map = new Hashmap<> (initialcapacity); }
2, HashSet common methods
boolean Add (E): If the specified element is not already contained in this set, the specified element is added
Public boolean Add (E) { //Call map's Put method, where value value is static object return Map.put (E, PRESENT) ==null; }
void Clear (): Removes all elements from this set
public void Clear () { map.clear (); }
Object Clone (): Returns a shallow copy of this HashSet instance
Public Object Clone () { try { //Call the parent class's Clone method hashset<e> Newset = (hashset<e>) Super.clone (); Newset.map = (hashmap<e, object>) Map.clone (); return newset; } catch (clonenotsupportedexception e) { throw new Internalerror (e); } }
Boolean contains (Object o): Returns true if this set contains the specified element
Public Boolean contains (Object o) { return Map.containskey (o); }
boolean isEmpty (): Returns true if this set contains no elements
public boolean isEmpty () { return map.isempty (); }
iterator<e> Iterator (): Returns an iterator that iterates over the elements in this set
Public iterator<e> Iterator () { return Map.keyset (). Iterator ();
boolean remove (Object o): If the specified element is present in this set, remove it
public boolean remove (Object o) { return Map.Remove (o) ==present; }
int size (): Returns the number of elements in this set
public int size () { return map.size (); }
Third, HashSet application example code
public class hashsetdemo{public static void Main (string[] args) {hashset<string> HS1 = new Hashset< ;> (); The parameterless constructor creates a new HashSet System.out.println ("Call the Add function") with a default size of 16 and a loading factor of 0.75. Hs1.add ("Hello"); Hs1.add ("World"); Hs1.add ("Nihao"); Hashset<string> HS2 = new hashset<> (HS1); Constructs a hashset System.out.println (called the Remove function) that contains the elements in the HS1; Hs1.remove ("Hello"); for (String STR:HS1) System.out.println (str); SYSTEM.OUT.PRINTLN ("Call the Clone function"); Hashset<string> hs3= (hashset<string>) Hs2.clone (); for (String STR:HS3) System.out.println (str); System.out.println ("Using iterators to traverse elements in HashSet"); Iterator<string> It=hs2.iterator (); while (It.hasnext ()) {System.out.println (It.next ()); } System.out.println ("Call size function"); System.out.print (Hs2.size ()); }}
Execution results
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Java Collection series of HashSet source code analysis