Java HashSet
Java HashSet class is used to create a collection that uses a hash table for storage. It inherits the AbstractSet class and implements Set interface.
The important points about Java HashSet class are:
HashSet stores the elements by using a mechanism called hashing.
HashSet contains unique elements only.
HashSet allows null value.
HashSet class is non synchronized.
HashSet doesn't maintain the insertion order. Here, elements are inserted on the basis of their hashcode.
HashSet is the best approach for search operations.
The initial default capacity of HashSet is 16, and the load factor is 0.75.
Difference between List and Set
A list can contain duplicate elements whereas Set contains unique elements only.
Hierarchy of HashSet class
The HashSet class extends AbstractSet class which implements Set interface. The Set interface inherits Collection and Iterable interfaces in hierarchical order.
HashSet class declaration
Let's see the declaration for java.util.HashSet class.
- public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloeable, Serializable
Constructors of Java HashSet class
SN | Constructor | Description |
1) | HashSet() | It is used to construct a default HashSet. |
2) | HashSet(int capacity) | It is used to initialize the capacity of the hash set to the given integer value capacity. The capacity grows automatically as elements are added to the HashSet. |
3) | HashSet(int capacity, float loadFactor) | It is used to initialize the capacity of the hash set to the given integer value capacity and the specified load factor. |
4) | HashSet(Collection<? extends E> c) | It is used to initialize the hash set by using the elements of the collection c. |
Methods of Java HashSet class
Various methods of Java HashSet class are as follows:
SN | Modifier & Type | Method | Description | ||||
1) | boolean | add(E e) | It is used to add the specified element to this set if it is not already present. | ||||
2) | void | clear() | It is used to remove all of the elements from the set. | ||||
3) | object | clone() | It is used to return a shallow copy of this HashSet instance: the elements themselves are not cloned. | ||||
4) | boolean | contains(Object o) | It is used to return true if this set contains the specified element. | ||||
5) | boolean | isEmpty() | It is used to return true if this set contains no elements. | ||||
6) | Iterator<E> | iterator() | It is used to return an iterator over the elements in this set. | ||||
7) | boolean | remove(Object o) | It is used to remove the specified element from this set if it is present. | ||||
8) | int | size() | It is used to return the number of elements in the set. | ||||
9) | Spliterator<E> | spliterator() | It is used to create a late-binding and fail-fast Spliterator over the elements in the set. |
Java HashSet Example
Let's see a simple example of HashSet. Notice, the elements iterate in an unordered collection.
import java.util.*;
class HashSet1{
public static void main(String args[]){
//Creating HashSet and adding elements
HashSet<String> set=new HashSet();
set.add("One");
set.add("Two");
set.add("Three");
set.add("Four");
set.add("Five");
Iterator<String> i=set.iterator();
while(i.hasNext())
{
System.out.println(i.next());
}
}
}
Five
One
Four
Two
Three
Java HashSet example ignoring duplicate elements
In this example, we see that HashSet doesn't allow duplicate elements.
import java.util.*;
class HashSet2{
public static void main(String args[]){
//Creating HashSet and adding elements
HashSet<String> set=new HashSet<String>();
set.add("Ravi");
set.add("Vijay");
set.add("Ravi");
set.add("Ajay");
//Traversing elements
Iterator<String> itr=set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Ajay
Vijay
Ravi
Java HashSet example to remove elements
Here, we see different ways to remove an element.
import java.util.*;
class HashSet3{
public static void main(String args[]){
HashSet<String> set=new HashSet<String>();
set.add("Ravi");
set.add("Vijay");
set.add("Arun");
set.add("Sumit");
System.out.println("An initial list of elements: "+set);
//Removing specific element from HashSet
set.remove("Ravi");
System.out.println("After invoking remove(object) method: "+set);
HashSet<String> set1=new HashSet<String>();
set1.add("Ajay");
set1.add("Gaurav");
set.addAll(set1);
System.out.println("Updated List: "+set);
//Removing all the new elements from HashSet
set.removeAll(set1);
System.out.println("After invoking removeAll() method: "+set);
//Removing elements on the basis of specified condition
set.removeIf(str->str.contains("Vijay"));
System.out.println("After invoking removeIf() method: "+set);
//Removing all the elements available in the set
set.clear();
System.out.println("After invoking clear() method: "+set);
}
}
An initial list of elements: [Vijay, Ravi, Arun, Sumit]
After invoking remove(object) method: [Vijay, Arun, Sumit]
Updated List: [Vijay, Arun, Gaurav, Sumit, Ajay]
After invoking removeAll() method: [Vijay, Arun, Sumit]
After invoking removeIf() method: [Arun, Sumit]
After invoking clear() method: []
Java HashSet from another Collection
import java.util.*;
class HashSet4{
public static void main(String args[]){
ArrayList<String> list=new ArrayList<String>();
list.add("Ravi");
list.add("Vijay");
list.add("Ajay");
HashSet<String> set=new HashSet(list);
set.add("Gaurav");
Iterator<String> i=set.iterator();
while(i.hasNext())
{
System.out.println(i.next());
}
}
}
Vijay
Ravi
Gaurav
Ajay
Java HashSet Example: Book
Let's see a HashSet example where we are adding books to set and printing all the books.
import java.util.*;
class Book {
int id;
String name,author,publisher;
int quantity;
public Book(int id, String name, String author, String publisher, int quantity) {
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
}
public class HashSetExample {
public static void main(String[] args) {
HashSet<Book> set=new HashSet<Book>();
//Creating Books
Book b1=new Book(101,"Let us C","Yashwant Kanetkar","BPB",8);
Book b2=new Book(102,"Data Communications & Networking","Forouzan","Mc Graw Hill",4);
Book b3=new Book(103,"Operating System","Galvin","Wiley",6);
//Adding Books to HashSet
set.add(b1);
set.add(b2);
set.add(b3);
//Traversing HashSet
for(Book b:set){
System.out.println(b.id+" "+b.name+" "+b.author+" "+b.publisher+" "+b.quantity);
}
}
}
Output:
101 Let us C Yashwant Kanetkar BPB 8
102 Data Communications & Networking Forouzan Mc Graw Hill 4
103 Operating System Galvin Wiley 6
Java LinkedHashSet Class
Java LinkedHashSet class is a Hashtable and Linked list implementation of the Set interface. It inherits the HashSet class and implements the Set interface.
The important points about the Java LinkedHashSet class are:
Java LinkedHashSet class contains unique elements only like HashSet.
Java LinkedHashSet class provides all optional set operations and permits null elements.
Java LinkedHashSet class is non-synchronized.
Java LinkedHashSet class maintains insertion order.
Note: Keeping the insertion order in the LinkedHashset has some additional costs, both in terms of extra memory and extra CPU cycles. Therefore, if it is not required to maintain the insertion order, go for the lighter-weight HashMap or the HashSet instead.
Hierarchy of LinkedHashSet class
The LinkedHashSet class extends the HashSet class, which implements the Set interface. The Set interface inherits Collection and Iterable interfaces in hierarchical order.
LinkedHashSet Class Declaration
Let's see the declaration for java.util.LinkedHashSet class.
- public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, Serializable
Constructors of Java LinkedHashSet Class
Constructor | Description |
HashSet() | It is used to construct a default HashSet. |
HashSet(Collection c) | It is used to initialize the hash set by using the elements of the collection c. |
LinkedHashSet(int capacity) | It is used to initialize the capacity of the linked hash set to the given integer value capacity. |
LinkedHashSet(int capacity, float fillRatio) | It is used to initialize both the capacity and the fill ratio (also called load capacity) of the hash set from its argument. |
Java LinkedHashSet Example
Let's see a simple example of the Java LinkedHashSet class. Here you can notice that the elements iterate in insertion order.
FileName: LinkedHashSet1.java
import java.util.*;
class LinkedHashSet1{
public static void main(String args[]){
//Creating HashSet and adding elements
LinkedHashSet<String> set=new LinkedHashSet();
set.add("One");
set.add("Two");
set.add("Three");
set.add("Four");
set.add("Five");
Iterator<String> i=set.iterator();
while(i.hasNext())
{
System.out.println(i.next());
}
}
}
Output:
One
Two
Three
Four
Five
Note: We can also use the enhanced for loop for displaying the elements.
Java LinkedHashSet example ignoring duplicate Elements
sFileName: LinkedHashSet2.java
import java.util.*;
class LinkedHashSet2{
public static void main(String args[]){
LinkedHashSet<String> al=new LinkedHashSet<String>();
al.add("Ravi");
al.add("Vijay");
al.add("Ravi");
al.add("Ajay");
Iterator<String> itr=al.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Ravi
Vijay
Ajay
Remove Elements Using LinkedHashSet Class
FileName: LinkedHashSet3.java
- import java.util.*;
public class LinkedHashSet3
{
// main method
public static void main(String args[])
{
// Creating an empty LinekdhashSet of string type
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
// Adding elements to the above Set
// by invoking the add() method
lhs.add("Java");
lhs.add("T");
lhs.add("Point");
lhs.add("Good");
lhs.add("Website");
// displaying all the elements on the console
System.out.println("The hash set is: " + lhs);
- // Removing an element from the above linked Set
// since the element "Good" is present, therefore, the method remove()
// returns true
System.out.println(lhs.remove("Good"));
// After removing the element
System.out.println("After removing the element, the hash set is: " + lhs);
// since the element "For" is not present, therefore, the method remove()
// returns false
System.out.println(lhs.remove("For"));
}
}
Output:
The hash set is: [Java, T, Point, Good, Website]
true
After removing the element, the hash set is: [Java, T, Point, Website]
false
Java LinkedHashSet Example: Book
FileName: Book.java
import java.util.*;
class Book {
int id;
String name,author,publisher;
int quantity;
public Book(int id, String name, String author, String publisher, int quantity) {
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
}
public class LinkedHashSetExample {
public static void main(String[] args) {
LinkedHashSet<Book> hs=new LinkedHashSet<Book>();
//Creating Books
Book b1=new Book(101,"Let us C","Yashwant Kanetkar","BPB",8);
Book b2=new Book(102,"Data Communications & Networking","Forouzan","Mc Graw Hill",4);
Book b3=new Book(103,"Operating System","Galvin","Wiley",6);
//Adding Books to hash table
hs.add(b1);
hs.add(b2);
hs.add(b3);
//Traversing hash table
for(Book b:hs){
System.out.println(b.id+" "+b.name+" "+b.author+" "+b.publisher+" "+b.quantity);
}
}
}
Output:
101 Let us C Yashwant Kanetkar BPB 8
102 Data Communications & Networking Forouzan Mc Graw Hill 4
103 Operating System Galvin Wiley 6
Java TreeSet class
Java TreeSet class implements the Set interface that uses a tree for storage. It inherits AbstractSet class and implements the NavigableSet interface. The objects of the TreeSet class are stored in ascending order.
The important points about the Java TreeSet class are:
Java TreeSet class contains unique elements only like HashSet.
Java TreeSet class access and retrieval times are quiet fast.
Java TreeSet class doesn't allow null element.
Java TreeSet class is non synchronized.
Java TreeSet class maintains ascending order.
Java TreeSet class contains unique elements only like HashSet.
Java TreeSet class access and retrieval times are quite fast.
The TreeSet can only allow those generic types that are comparable. For example The Comparable interface is being implemented by the StringBuffer class.
Internal Working of The TreeSet Class
TreeSet is being implemented using a binary search tree, which is self-balancing just like a Red-Black Tree. Therefore, operations such as a search, remove, and add consume O(log(N)) time. The reason behind this is there in the self-balancing tree. It is there to ensure that the tree height never exceeds O(log(N)) for all of the mentioned operations. Therefore, it is one of the efficient data structures in order to keep the large data that is sorted and also to do operations on it.
Synchronization of The TreeSet Class
As already mentioned above, the TreeSet class is not synchronized. It means if more than one thread concurrently accesses a tree set, and one of the accessing threads modify it, then the synchronization must be done manually. It is usually done by doing some object synchronization that encapsulates the set. However, in the case where no such object is found, then the set must be wrapped with the help of the Collections.synchronizedSet() method. It is advised to use the method during creation time in order to avoid the unsynchronized access of the set. The following code snippet shows the same.
TreeSet treeSet = new TreeSet();
Set syncrSet = Collections.synchronziedSet(treeSet);
Hierarchy of TreeSet class
As shown in the above diagram, the Java TreeSet class implements the NavigableSet interface. The NavigableSet interface extends SortedSet, Set, Collection and Iterable interfaces in hierarchical order.
TreeSet Class Declaration
Let's see the declaration for java.util.TreeSet class.
- public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable
Constructors of Java TreeSet Class
Constructor | Description |
TreeSet() | It is used to construct an empty tree set that will be sorted in ascending order according to the natural order of the tree set. |
TreeSet(Collection<? extends E> c) | It is used to build a new tree set that contains the elements of the collection c. |
TreeSet(Comparator<? super E> comparator) | It is used to construct an empty tree set that will be sorted according to given comparator. |
TreeSet(SortedSet<E> s) | It is used to build a TreeSet that contains the elements of the given SortedSet. |
Methods of Java TreeSet Class
Method | Description |
boolean add(E e) | It is used to add the specified element to this set if it is not already present. |
boolean addAll(Collection<? extends E> c) | It is used to add all of the elements in the specified collection to this set. |
E ceiling(E e) | It returns the equal or closest greatest element of the specified element from the set, or null there is no such element. |
Comparator<? super E> comparator() | It returns a comparator that arranges elements in order. |
Iterator descendingIterator() | It is used to iterate the elements in descending order. |
NavigableSet descendingSet() | It returns the elements in reverse order. |
E floor(E e) | It returns the equal or closest least element of the specified element from the set, or null there is no such element. |
SortedSet headSet(E toElement) | It returns the group of elements that are less than the specified element. |
NavigableSet headSet(E toElement, boolean inclusive) | It returns the group of elements that are less than or equal to(if, inclusive is true) the specified element. |
E higher(E e) | It returns the closest greatest element of the specified element from the set, or null there is no such element. |
Iterator iterator() | It is used to iterate the elements in ascending order. |
E lower(E e) | It returns the closest least element of the specified element from the set, or null there is no such element. |
E pollFirst() | It is used to retrieve and remove the lowest(first) element. |
E pollLast() | It is used to retrieve and remove the highest(last) element. |
Spliterator spliterator() | It is used to create a late-binding and fail-fast spliterator over the elements. |
NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) | It returns a set of elements that lie between the given range. |
SortedSet subSet(E fromElement, E toElement)) | It returns a set of elements that lie between the given range which includes fromElement and excludes toElement. |
SortedSet tailSet(E fromElement) | It returns a set of elements that are greater than or equal to the specified element. |
NavigableSet tailSet(E fromElement, boolean inclusive) | It returns a set of elements that are greater than or equal to (if, inclusive is true) the specified element. |
boolean contains(Object o) | It returns true if this set contains the specified element. |
boolean isEmpty() | It returns true if this set contains no elements. |
boolean remove(Object o) | It is used to remove the specified element from this set if it is present. |
void clear() | It is used to remove all of the elements from this set. |
Object clone() | It returns a shallow copy of this TreeSet instance. |
E first() | It returns the first (lowest) element currently in this sorted set. |
E last() | It returns the last (highest) element currently in this sorted set. |
int size() | It returns the number of elements in this set. |
Java TreeSet Examples
Java TreeSet Example 1:
Let's see a simple example of Java TreeSet.
FileName: TreeSet1.java
import java.util.*;
class TreeSet1{
public static void main(String args[]){
//Creating and adding elements
TreeSet<String> al=new TreeSet<String>();
al.add("Ravi");
al.add("Vijay");
al.add("Ravi");
al.add("Ajay");
//Traversing elements
Iterator<String> itr=al.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Ajay Ravi Vijay
Java TreeSet Example 2:
Let's see an example of traversing elements in descending order.
FileName: TreeSet2.java
import java.util.*;
class TreeSet2{
public static void main(String args[]){
TreeSet<String> set=new TreeSet<String>();
set.add("Ravi");
set.add("Vijay");
set.add("Ajay");
System.out.println("Traversing element through Iterator in descending order");
Iterator i=set.descendingIterator();
while(i.hasNext())
{
System.out.println(i.next());
}
}
}
Output:
Traversing element through Iterator in descending order Vijay Ravi Ajay Traversing element through NavigableSet in descending order Vijay Ravi Ajay
Java TreeSet Example 3:
Let's see an example to retrieve and remove the highest and lowest Value.
FileName: TreeSet3.java
import java.util.*;
class TreeSet3{
public static void main(String args[]){
TreeSet<Integer> set=new TreeSet<Integer>();
set.add(24);
set.add(66);
set.add(12);
set.add(15);
System.out.println("Lowest Value: "+set.pollFirst());
System.out.println("Highest Value: "+set.pollLast());
}
}
Output:
Lowest Value: 12
Highest Value: 66
Java TreeSet Example 4:
In this example, we perform various NavigableSet operations.
FileName: TreeSet4.java
import java.util.*;
class TreeSet4{
public static void main(String args[]){
TreeSet<String> set=new TreeSet<String>();
set.add("A");
set.add("B");
set.add("C");
set.add("D");
set.add("E");
System.out.println("Initial Set: "+set);
- System.out.println("Reverse Set: "+set.descendingSet());
- System.out.println("Head Set: "+set.headSet("C", true));
- System.out.println("SubSet: "+set.subSet("A", false, "E", true));
System.out.println("TailSet: "+set.tailSet("C", false));
}
}
Output:
Initial Set: [A, B, C, D, E]
Reverse Set: [E, D, C, B, A]
Head Set: [A, B, C]
SubSet: [B, C, D, E]
TailSet: [D, E]
Java TreeSet Example 5:
In this example, we perform various SortedSetSet operations.
FileName: TreeSet5.java
import java.util.*;
class TreeSet5{
public static void main(String args[]){
TreeSet<String> set=new TreeSet<String>();
set.add("A");
set.add("B");
set.add("C");
set.add("D");
set.add("E");
- System.out.println("Intial Set: "+set);
- System.out.println("Head Set: "+set.headSet("C"));
- System.out.println("SubSet: "+set.subSet("A", "E"));
System.out.println("TailSet: "+set.tailSet("C"));
}
}
Output:
Intial Set: [A, B, C, D, E]
Head Set: [A, B]
SubSet: [A, B, C, D]
TailSet: [C, D, E]
Java TreeSet Example: Book
Let's see a TreeSet example where we are adding books to the set and printing all the books. The elements in TreeSet must be of a Comparable type. String and Wrapper classes are Comparable by default. To add user-defined objects in TreeSet, you need to implement the Comparable interface.
FileName: TreeSetExample.java
import java.util.*;
class Book implements Comparable<Book>{
int id;
String name,author,publisher;
int quantity;
public Book(int id, String name, String author, String publisher, int quantity) {
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.quantity = quantity;
}
//Abstract methods are those types of methods that don't require implementation for its declaration. These methods don't have a body which means no implementation. A few properties of an abstract method are: An abstract method in Java is declared through the keyword “abstract”.
// implementing the abstract method
public int compareTo(Book b) {
if(id>b.id){
return 1;
}else if(id<b.id){
return -1;
}else{
return 0;
}
}
}
public class TreeSetExample {
public static void main(String[] args) {
Set<Book> set=new TreeSet<Book>();
//Creating Books
Book b1=new Book(121,"Let us C","Yashwant Kanetkar","BPB",8);
Book b2=new Book(233,"Operating System","Galvin","Wiley",6);
Book b3=new Book(101,"Data Communications & Networking","Forouzan","Mc Graw Hill",4);
//Adding Books to TreeSet
set.add(b1);
set.add(b2);
set.add(b3);
//Traversing TreeSet
for(Book b:set){
System.out.println(b.id+" "+b.name+" "+b.author+" "+b.publisher+" "+b.quantity);
}
}
}
Output:
101 Data Communications & Networking Forouzan Mc Graw Hill 4
121 Let us C Yashwant Kanetkar BPB 8
233 Operating System Galvin Wiley 6
ClassCast Exception in TreeSet
If we add an object of the class that is not implementing the Comparable interface, the ClassCast Exception is raised. Observe the following program.
FileName: ClassCastExceptionTreeSet.java
// important import statement
import java.util.*;
class Employee
{
int empId;
String name;
// getting the name of the employee
String getName()
{
return this.name;
}
// setting the name of the employee
void setName(String name)
{
this.name = name;
}
// setting the employee id
// of the employee
void setId(int a)
{
this.empId = a;
}
// retrieving the employee id of
// the employee
int getId()
{
return this.empId;
}
- }
public class ClassCastExceptionTreeSet
{
// main method
public static void main(String[] args)
{
// creating objects of the class Employee
Employee obj1 = new Employee();
- Employee obj2 = new Employee();
- TreeSet<Employee> ts = new TreeSet<Employee>();
// adding the employee objects to
// the TreeSet class
ts.add(obj1);
ts.add(obj2);
- System.out.println("The program has been executed successfully.");
}
}
When we compile the above program, we get the ClassCastException, as shown below.
Exception in thread "main" java.lang.ClassCastException: class Employee cannot be cast to class java.lang.Comparable (Employee is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
at java.base/java.util.TreeMap.compare(TreeMap.java:1569)
at java.base/java.util.TreeMap.addEntryToEmptyMap(TreeMap.java:776)
at java.base/java.util.TreeMap.put(TreeMap.java:785)
at java.base/java.util.TreeMap.put(TreeMap.java:534)
at java.base/java.util.TreeSet.add(TreeSet.java:255)
at ClassCastExceptionTreeSet.main(ClassCastExceptionTreeSet.java:52)
Explanation: In the above program, it is required to implement a Comparable interface. It is because the TreeSet maintains the sorting order, and for doing the sorting the comparison of different objects that are being inserted in the TreeSet is must, which is accomplished by implementing the Comparable interface.