1. Java hashSet and Set
Before we learn about Java hashSet class, we will learn about the Set interface. Because the HashSet class implements Java Collection’s Set interface. The Set Interface ensures the implementing class to hold uniqueness in the collection. Means, it does not allow duplicate items. In Java Collection framework, the below classes implement the Set interface:
- HashSet
- EnumSet
- TreeSet
There were other classes as well. But here we listed frequently used ones. In this example, we will explore about the HashSet collection class.
2. Set Interface Methods
Since hashSet signs the contract for the Set interface, it supports the methods exposed by the Set interface. Below table shows commonly used Set Interface methods and its description:
Method | Description |
boolean add(E e) | Adds Element E to the Set. The interface does not allow adding a duplicate element |
boolean remove(E e) | Removes an Element E from the Set. |
void clear() | Removes all the elements. Keeps the Set Empty. |
boolean isEmpty() | Tells the Set is empty or not. |
int size() | Returns number of elements in the Set. |
boolean contains(Object o) | Searches the Unique elements in the Set and returns true when ‘o’ is found. |
Iterator<E> iterator | Returns an iterator to iterate over unique elements present in this set. |
3. Java Collection Class – hashSet
The hashSet class in Java Collection implements both Collection & Set Interfaces. Java hashSet does not keep insertion order. Say, for example, if we insert Item1, Item2 and Item3 into HashSet, the hashSet does not assure that it will store the items in the same insertion order. The HashSet operates on Hash Table, which we will study later in more details. For now, you can imagine a hash table as Buckets with a collection of items in it. And Java’s algorithm makes sure the items are spread evenly among these buckets by using the hashCode function.
The items stored in the hashSet collection must override the hashCode and equals methods. This is pointed out in the below two videos.
Comparing Two Objects
Override hashCode Method
4. Java HashSet Example
In our previous example, we used the Product Class instance as the collection item. Here also we will use the same product class. Refer the code for the product class in the Java ArrayList Example.
4.1 Override equals Method
The hashSet class works perfectly when we override the
equals and
hashCode methods. First, let us override the equals method. We must override this method on the Product
class as we store the instance of it in the hashSet. Now have a look at the override below:
1 2 3 4 5 6 7 8 |
@Override public boolean equals(Object obj) { System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); System.out.println("Collection Called our equals method"); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); Product prod = (Product) obj; return (this.ProdId == prod.getProdId()); } |
The method returns true when the current instance’s ProdId
matches with the passed-in ProdId
. The hashSet
class will use this method to know how to compare two objects. Now hashSet class says two products are equals when their product IDs match. Note, our implementation does not compare the product names.
4.2 Override hashCode Method
Our Product
class needs one more override. It is
hashCode method. Java’s hashing algorithm depends heavily on this and we will learn more about this hashing later. For now, we will see how to override this method for our Product
class. Have a look at the below code:
1 2 3 4 5 6 7 8 9 |
@Override public int hashCode() { int x = Objects.hashCode(ProdId); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); System.out.println("Collection Called our hashCode"); System.out.println("Hash code for " + this.ProdName + " is : " + x); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); return x; } |
Java recommends overriding the hashCode method whenever you override the equals method. In the past section we already overrode the equals method for the Product class. The equal method involves only the ProdId for the comparison. So, our hashCode generation method also should depend only on the Product ID. Since, we are using the Java 8, it is easy to set up the hashCode. In the above code at line 1, we call the hashCode static method on the Objects class and pass only the ProdId to make a hash code out of it. Now our product class is eligible for any hashing-based collection class like hashSet.
4.3 Create hashSet and Add Items
We set our Product
class with required overrides. Now, we will create the instances of it and add to the hashSet
. Below is the code snippet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class HashSetTest { public static void main(String[] args) { //Sample02: Create a HashSet and hold it in Set Interface Set<Product> Products = new HashSet<Product>(); //Sample 03: Construct Sample Products Product p1 = new Product(101, "Pen"); Product p2 = new Product(102, "Pencil"); Product p3 = new Product(103, "Rubber"); Product p4 = new Product(104, "Writing Pad"); Product p5 = new Product(105, "Clips"); Product p6 = new Product(106, "Sharpner"); //Sample 05: Add Products to HashSet Products.add(p1); Products.add(p2); Products.add(p3); Products.add(p4); Products.add(p5); Products.add(p6); printProducts(Products); |
At line 4, we create an instance of the
hashSet and hold its reference as
Set type. Note,
hashSet implements
Set interface. Next, we create six products and add it to the hashSet
using the
add method. Finally, we print the content of the hashSet
using the custom function printProducts
. We will write it in the next section.
4.4 Print hashSet
The code below iterates the hashSet
of products and print each product in the console window. Here, we use the for each construct to list the products in the console output window.
1 2 3 4 5 6 7 8 |
//Sample 04: List the Products private static void printProducts(Set<Product> Products) { System.out.println("Product Details:-"); for(Product prod: Products){ System.out.println(prod); } System.out.println("=================="); } |
4.5 Test Adding Duplicate Items to Java hashSet
Remember, the Set
interface implementation does not allow duplicates. In this section, we will try to add duplicate products and see what happens. Have a look at the below code:
1 2 3 4 5 6 7 8 9 |
//Sample 06: Add a Duplicate Product Product p7 = new Product(104, "Writing Pad"); Product p8 = new Product(104, "Name NA"); boolean ret = Products.add(p7); if (!ret) System.out.println("Product " + p7 + " Already Exists!"); ret = Products.add(p8); if (!ret) System.out.println("Product " + p8 + " Already Exists!"); |
At line 2,3 we create two new products in the heap. Our hashSet
already contains a product [104, Writing Pad]. So, adding the new product p7
is not allowed. But hashSet
above does not allow adding the product p8 also, even though the name is not Writing Pad.
Since hashSet
need to maintain unique products, it checks for duplicate before adding any new product. It uses our
equals override to know the products are same. Our equals
override compares only Product ID. This is how product p8
is rejected by the hashSet as its id is 104 and it already exists in it. You can look at the console window to see how it invokes the overrides.
4.6 Java hashSet remove Method
Does removing a product require any comparison? The code snippet is below:
1 2 3 4 5 6 7 8 9 10 11 |
//Sample 07: Remove a Product ret = Products.remove(p3); if (!ret) System.out.println("Product " + p3 + " Not there"); ret = Products.remove(p5); if (!ret) System.out.println("Product " + p5 + " Not there"); ret = Products.remove(p5); if (!ret) System.out.println("Product " + p3 + " Not there"); printProducts(Products); |
In the above code, we try to remove product p3 two times. We call
remove method of the hashSet
and pass a Product
instance to remove. The hashSet
class compares the collection items with the passed-in parameter. When there is a match, it removes that specific item. So, the remove method of the hashSet
also depends on our equals method override. In the above code, remove method call at Line No 8 fails.
4.7 The contains Method Of Java hashSet
The
contains method of the hashSet
is used to check whether a specific product exists in the collection. The method returns true when the item exists in the collection. In our code below, we check product p2
and p5
exists in the collection. Since we removed p5 in the previous section, the second call to the contains
method will fail.
1 2 3 |
//Sample 08: Check product Already Exists ret = Products.contains(p2); ret = Products.contains(p5); |
5. Complete Code Example – Java hashSet
5.1 Modified Product 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
import java.util.Objects; public class Product { private int ProdId; private String ProdName; // 1.1: Ctor Product(int id, String name) { ProdId = id; ProdName = name; } // 1.2: toString Override @Override public String toString() { return ProdId + ":" + ProdName ; } //1.3 Getter and Setter public int getProdId() { return ProdId; } public void setProdId(int prodId) { ProdId = prodId; } public String getProdName() { return ProdName; } public void setProdName(String prodName) { ProdName = prodName; } //Sample 02: Modify HashCode and Equals to print hash code @Override public int hashCode() { int x = Objects.hashCode(ProdId); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); System.out.println("Collection Called our hashCode"); System.out.println("Hash code for " + this.ProdName + " is : " + x); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); return x; } @Override public boolean equals(Object obj) { System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); System.out.println("Collection Called our equals method"); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); Product prod = (Product) obj; return (this.ProdId == prod.getProdId()); } } |
5.2 The HashSetTest 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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
//Sample01: Set & HashSet part of Util Package import java.util.HashSet; import java.util.Set; public class HashSetTest { public static void main(String[] args) { //Sample02: Create a HashSet and hold it in Set Interface Set<Product> Products = new HashSet<Product>(); //Sample 03: Construct Sample Products Product p1 = new Product(101, "Pen"); Product p2 = new Product(102, "Pencil"); Product p3 = new Product(103, "Rubber"); Product p4 = new Product(104, "Writing Pad"); Product p5 = new Product(105, "Clips"); Product p6 = new Product(106, "Sharpner"); //Sample 05: Add Products to HashSet Products.add(p1); Products.add(p2); Products.add(p3); Products.add(p4); Products.add(p5); Products.add(p6); printProducts(Products); //Sample 06: Add a Duplicate Product Product p7 = new Product(104, "Writing Pad"); Product p8 = new Product(104, "Name NA"); boolean ret = Products.add(p7); if (!ret) System.out.println("Product " + p7 + " Already Exists!"); ret = Products.add(p8); if (!ret) System.out.println("Product " + p8 + " Already Exists!"); //Sample 07: Remove a Product ret = Products.remove(p3); if (!ret) System.out.println("Product " + p3 + " Not there"); ret = Products.remove(p5); if (!ret) System.out.println("Product " + p5 + " Not there"); ret = Products.remove(p5); if (!ret) System.out.println("Product " + p3 + " Not there"); printProducts(Products); //Sample 08: Check product Already Exists ret = Products.contains(p2); ret = Products.contains(p5); } //Sample 04: List the Products private static void printProducts(Set<Product> Products) { System.out.println("Product Details:-"); for(Product prod: Products){ System.out.println(prod); } System.out.println("=================="); } } |
6. Watch hashSet Example as YouTube
Categories: Java
Tags: add method, contains method, equals override, hashCode Override, remove method, Set Interface