Set/HashSet has only unique elements. Hence it contains no duplicate element. So if we want to add elements in the set then we write code like this
SetExample.java:
-------------------------
package in.anyforum;
public class SetExample{
public static void main(String[] args)
{
// TODO Auto-generated method stub
HashSet<Object> hashset = new HashSet<Object>();
hashset.add(2);
hashset.add("anyforum");
hashset.add("in");
System.out.println("Set is "+hashset);
}
}
============================= Output =============================
Set is [2, anyforum, in]
Now let´s add some duplicate element in the above code
SetExample2.java:
--------------------------
package in.anyforum;
public class SetExample2 {
public static void main(String[] args)
{
HashSet<Object> hashset = new HashSet<Object>();
hashset.add(2);
hashset.add("anyforum");
hashset.add("in");
hashset.add(2); // duplicate elements
hashset.add("anyforum"); // duplicate elements
System.out.println("Set is "+hashset);
}
}
============================= Output =============================
Set is [2, anyforum, in]
Now, what actually happens internally when we pass duplicate elements in the add() method, It will return false and do not add to the HashSet, if the element is already present in Set.
********************* But the main point arises that is how it returns false. *********************
When we notice the HashSet implementation of the add() method in Java APIs that is rt.jar, you will see the following code in it:
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
// SOME CODE ,i.e Other methods in Hash Set
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
// SOME CODE ,i.e Other methods in Hash Set
}
So, we are maintaining uniqueness in Set, internally in java through HashMap. Whenever we create an object of HashSet it will create an object of HashMap internally as we can see in the italic lines in the above code. To see the how HashMap works internally
click here.
As we know in HashMap each key is unique. So what we do in the set is that we pass the argument in the add(Elemene E) that is E as a key in the HashMap. Now we need to associate some value to the key, so what Java APIs developer did is to pass the Dummy value that is ( new Object () ) which is referred by Object reference PRESENT .
So, actually when you are adding a line in HashSet like hashset.add(2) what java does internally is that it will put that element E here 2 as a key in the HashMap(created during HashSet object creation) and some dummy value that is Object´s object is passed as a value to the key .
Now if you notice the code of the HashMap put(Key k,Value V) method, you will find something like this
public V put(K key, V value) {
//Some code
}
The main point to be noticed in above code is that put (key,value) will return
1. null , if key is unique and added to the map
2. Old Value of the key , if key is duplicate
So, in HashSet add() method, we check the return value of map.put(key,value) method with null value
i.e.
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
So, if map.put(key,value) returns null, then
map.put(e, PRESENT)==null will return true and element is added to the HashSet.
So, if map.put(key,value) returns old value of the key, then
map.put(e, PRESENT)==null will return false and element is not added to the HashSet.