Table of Contents
In this post, we will see about Hashset in java
Java HashSet:
1 2 3 4 5 |
Part-1:<a href="https://www.java2blog.com/2014/07/how-hashset-works-in-java.html">HashSet in java</a> Part-2:<a href="https://www.java2blog.com/2013/02/difference-between-hashmap-and-hashset.html">Difference between HashMap and HashSet</a>Â Part-3:<a href="https://www.java2blog.com/2014/02/hashcode-and-equals-method-in-java.html">hashcode and equals method in jav</a>a |
Lets first see introduction of Hashset then we will go through internals of it.
HashSet:
Definition of duplicate can be quite tricky sometimes.Lets consider two cases here.
- In case of primitive types(such as interger, String)
- In case of custom defined objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package org.arpit.java2blog; import java.util.HashSet; public class HashSetMain { public static void main(String[] args) { HashSet nameSet=new HashSet(); nameSet.add("Arpit"); nameSet.add("Arpit"); nameSet.add("john"); System.out.println("size of nameSet="+nameSet.size()); System.out.println(nameSet); } } |
1 2 3 4 |
size of nameSet=2 [Arpit, john] |
In case of Custom Objects:
For understanding how HashSet will work in case of custom objects, you need to understand hashcode and equals method in java.Lets create a class called Country and implement only equals method in it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
package org.arpit.java2blog; public class Country { String name; long population; public String getName() { return name; } public void setName(String name){ this.name = name; } public long getPopulation() { return population; } public void setPopulation(long population) { this.population = population; } public String toString() { return name; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Country other = (Country) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } |
create main class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package org.arpit.java2blog; import java.util.HashSet; public class HashSetCountryMain { public static void main(String[] args) { HashSet countrySet=new HashSet(); Country india1=new Country(); india1.setName("India"); Country india2=new Country(); india2.setName("India"); countrySet.add(india1); countrySet.add(india2); System.out.println("size of nameSet="+countrySet.size()); System.out.println(countrySet); } } |
When you run above program, you will get following output:
1 2 3 4 |
size of nameSet=2 [India, India] |
Now you must be wondering even through two objects are equal why HashSet contains two values instead of one.This is because First HashSet calculates hashcode for that key object, if hashcodes are same then only it checks for equals method and because hashcode for above two country objects uses default hashcode method,Both will have different memory address hence different hashcode.
Now lets add hashcode method in above Country class
1 2 3 4 5 6 7 8 9 |
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } |
Run above main program again, you will get following output:
1 2 3 4 |
size of nameSet=1 [India] |
So now we have good understanding of HashSet, lets see its internal representation:
Internal working of HashSet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class HashSet extends AbstractSet implements Set, Cloneable, java.io.Serializable { private transient HashMap<E,Object> map; // PRESENT is dummy value which will be used as value in map private static final Object PRESENT = new Object(); /** * Constructs a empty map.so hash * */ public HashSet() { map = new HashMap<E,Object>(); } // return false if e is already present in HashSet public boolean add(E e) { return map.put(e, PRESENT)==null; } // other HashSet methods } |
PRESENT is dummy value which is used value for internal map.
Lets see add method:
1 2 3 4 5 6 |
// return false if e is already present in HashSet public boolean add(E e) { return map.put(e, PRESENT)==null; } |
- map.put(e,PRESENT) will return null, if element not present in that map. So map.put(e, PRESENT) == null will return true ,hence add method will return true and element will be added in HashSet.
- map.put(e,PRESENT) will return old value ,if element is already present in that map. So  map.put(e, PRESENT) == null will return false, hence add method will return false and element will not be added in HashSet.
Please go through  core java interview questions for beginners for more interview questions.