View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

HashSet in Java

Updated on 04/03/20251,884 Views

The HashSet class in Java is part of the Java Collections Framework and stores unique elements, automatically eliminating duplicates. Built on a hash table structure, HashSet offers fast operations like insertion, deletion, and retrieval, making it an efficient choice for handling data in modern applications. 

In this tutorial, you'll learn everything you need to know about HashSet—its definition, features, hierarchy, constructors, methods, and practical examples tailored to today's development needs.

Improve your Java programming skills with our Software Development courses — take the next step in your learning journey! 

Understanding HashSet in Java

HashSet is a class that implements the Set interface in Java. It stores a collection of elements where each element is guaranteed to be unique. HashSet is backed by a hash table, which helps achieve constant time complexity for basic operations like adding and removing elements.

Here are the key characteristics of HashSet:

  • If you attempt to add a duplicate element, it simply won’t be added to the collection. Additionally, the add() method returns false when a duplicate element is attempted to be added, indicating that the element was not inserted into the set. This can be useful if you want to check whether an element was successfully added to the HashSet.
  • The elements in a HashSet are not stored in any specific order, so the order in which they are retrieved may not match the order in which they were added.
  • HashSet allows only one null element. However, trying to add more than one null will result in only a single null element being stored.
  • The underlying hash table structure enables efficient insertion, deletion, and element lookup, making operations typically O(1), making it faster than many other data structures for these operations.

Here’s how HashSet differs from other set implementations (TreeSet, LinkedHashSet)

Feature

HashSet

TreeSet

LinkedHashSet

Ordering

No ordering (unordered)

Sorted (elements ordered by natural order or comparator)

Insertion order (preserves the order of elements as they are added)

Performance

Fast (constant time for add/remove)

Slower (logarithmic time for add/remove)

Moderate (slower than HashSet but faster than TreeSet)

Null Elements

Allows one null element

Does not allow null elements

Allows one null element

Use Case

General use cases with fast operations

When elements need to be sorted

When maintaining the insertion order is important

Also Read: Exploring the 14 Key Advantages of Java: Why It Remains a Developer's Top Choice in 2025

Now, let’s understand the working of Java HashSet operations.

Working with HashSet

Now that you understand the basic features of HashSet, let's dive into how you can work with it in Java. You'll learn how to create a HashSet, add and remove elements, check for the existence of elements, and iterate through a HashSet.

Creating a HashSet

To create a HashSet in Java, you can simply use its constructor. By default, a HashSet is created without any elements, but you can also initialize it with a collection of elements.

Example: Creating an Empty HashSet


import java.util.HashSet;

public class CreateHashSetExample {
public static void main(String[] args) {
// Creating an empty HashSet
HashSet<String> set = new HashSet<>();
System.out.println("HashSet created: " + set);
}
}

Explanation:

  • A HashSet<String> is created with no elements.
  • The default constructor is used to initialize the HashSet.

Output:

HashSet created: []

Adding Elements to HashSet

Adding elements to a HashSet is done using the add() method. It returns true if the element was successfully added and false if it already exists in the set.

Example: Adding Elements

import java.util.HashSet;

public class AddElementsExample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();

// Adding elements to the HashSet
set.add("Apple");
set.add("Banana");
set.add("Cherry");
set.add("Apple"); // Duplicate element, will not be added

System.out.println("HashSet after adding elements: " + set);
}
}

Explanation:

  • The add() method adds elements to the set.
  • Since "Apple" is already in the set, it is not added again.
  • HashSet automatically handles duplicates.

Output:

HashSet after adding elements: [Banana, Apple, Cherry]

Removing Elements from HashSet

To remove elements from a HashSet, you use the remove() method, which returns true if the element was successfully removed.

Example: Removing Elements

import java.util.HashSet;

public class RemoveElementsExample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();

set.add("Apple");
set.add("Banana");
set.add("Cherry");

// Removing an element from the HashSet
boolean removed = set.remove("Banana");

System.out.println("Was 'Banana' removed? " + removed);
System.out.println("HashSet after removal: " + set);
}
}

Explanation:

  • The remove() method removes the element "Banana" from the set and returns true since it was successfully removed.
  • After removal, the updated set is printed.

Output:

Was 'Banana' removed? true
HashSet after removal: [Apple, Cherry]

Checking for Existence of Elements

To check if an element exists in the HashSet, you use the contains() method. It returns true if the set contains the specified element.

Example: Checking for Existence

import java.util.HashSet;

public class ContainsExample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();

set.add("Apple");
set.add("Banana");
set.add("Cherry");

// Checking if an element exists in the HashSet
boolean hasApple = set.contains("Apple");
boolean hasOrange = set.contains("Orange");

System.out.println("Does the set contain 'Apple'? " + hasApple);
System.out.println("Does the set contain 'Orange'? " + hasOrange);
}
}

Explanation:

  • The contains() method checks if "Apple" and "Orange" are in the set.
  • It returns true for "Apple" and false for "Orange", since "Orange" was never added.

Output:

Does the set contain 'Apple'? true
Does the set contain 'Orange'? false

Iterating Through a HashSet

To iterate through the elements of a HashSet, you can use a for-each loop or an Iterator. Since HashSet is unordered, the iteration order may not match the order in which the elements were added.

Example: Iterating Through a HashSet

import java.util.HashSet;

public class IterateHashSetExample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();

set.add("Apple");
set.add("Banana");
set.add("Cherry");

// Iterating through the HashSet using for-each loop
System.out.println("Iterating through HashSet:");
for (String fruit : set) {
System.out.println(fruit);
}
}
}

Explanation:

  • The for-each loop is used to iterate over the elements in the HashSet.
  • Since HashSet does not guarantee any order, the elements may appear in a different order than they were added.

Output:

Iterating through HashSet:
Banana
Apple
Cherry

Note: The order of output might vary due to the unordered nature of HashSet.

Also Read: Differences Between HashMap and HashTable in Java

These fundamental operations allow you to effectively work with a HashSet in Java. Now, let’s look at performance considerations and advanced usage of Java HashSet operations.

Performance and Efficiency

When working with HashSet in Java, understanding its performance and internal workings is crucial for optimizing operations in your applications. Let's dive into the time complexity of common Java HashSet operations, its internal structure, and when it is the best choice to use HashSet.

Time Complexity of HashSet Operations

The performance of HashSet operations is primarily determined by the underlying hash table structure. Most operations—adding, removing, and checking for existence of elements—are typically very fast and have constant time complexity, O(1), on average.

Operation

Time Complexity

Add (add())

O(1)

Remove (remove())

O(1)

Contains (contains())

O(1)

Iteration (iterator)

O(n)

  • Add: When you add an element to a HashSet, the hash code of the element is calculated and used to determine its position in the table. The average case time complexity is O(1).
  • Remove: Removing an element follows a similar process, and the average time complexity is O(1).
  • Contains: Checking for the presence of an element is typically O(1), as it relies on hashing to locate the element.

However, in the worst case (when there are too many hash collisions), the time complexity could degrade to O(n). But this situation is rare, especially if the hash function is well-distributed.

Internal Working of HashSet (HashMap)

HashSet uses a HashMap internally to store its elements as keys. The reason for this is that HashSet needs to store unique elements, and HashMap allows for efficient storage and lookup of keys (which, in the case of a HashSet, are the elements themselves). 

Here's how it works internally:

  • Hash Table: Internally, a HashSet uses a hash table (a HashMap without values) to store elements. The hash code of the element is calculated and used to determine its position in the table.
  • Buckets: The hash table is divided into buckets. Each bucket contains a list of entries that share the same hash code.
  • Collision Handling: If two elements have the same hash code, they will be stored in the same bucket. HashSet uses a technique called separate chaining (using a linked list or another structure to store elements that hash to the same bucket).

Example: HashSet Behind the Scenes

import java.util.HashSet;

public class HashSetInternalWorking {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Cherry");

// Internally, HashSet uses HashMap for storage
// HashSet stores elements as keys of the HashMap, and values are irrelevant
System.out.println("HashSet contents: " + set);
}
}

Explanation:

  • The HashSet is backed by a HashMap. Internally, the elements in the HashSet are stored as keys in the HashMap and the corresponding values are irrelevant (they are not used in the context of a HashSet).
  • In this example, you add three elements: "Apple", "Banana", and "Cherry".
  • The HashSet will store these elements as keys in the internal HashMap.
HashSet contents: [Apple, Banana, Cherry]

Each string is used as a key in a HashMap, and its corresponding value is irrelevant (not used in HashSet). This allows O(1) average time complexity for adding, removing, and checking for the existence of elements.

When to Use HashSet

While HashSet is efficient for most use cases, it's important to understand when it is the best choice for storing data.

1. When You Need Unique Elements: If you need to store a collection where duplicates are not allowed, HashSet is ideal. It automatically prevents duplicate entries.

2. When Order Does Not Matter: HashSet does not guarantee any specific order for its elements. If the order in which elements were added is not important, HashSet is a great choice for efficiency.

3. Fast Operations: If you need fast insertion, deletion, and lookups, HashSet provides O(1) average time complexity for these operations, making it highly efficient compared to other set implementations like TreeSet or LinkedHashSet, which have slower performance.

4. Handling Large Datasets: For large datasets where speed is a concern, HashSet provides an efficient way to check for membership and manage large collections of unique elements. This is particularly useful in scenarios such as caching, deduplication, or set operations (e.g., union, intersection).

Also Read: Careers in Java: How to Make a Successful Career in Java in 2025

To solidify your understanding of Java HashSet operations, test your knowledge with a quiz. It’ll help reinforce the concepts discussed throughout the tutorial and ensure you're ready to apply them in your projects.

Quiz to Test Your Knowledge on HashSet in Java

Assess your understanding of HashSet operations, performance, and best practices in Java by answering the following multiple-choice questions. Dive in!

1. Which of the following is a characteristic of HashSet in Java?

a) It allows duplicate elements.

b) It maintains the insertion order.

c) It allows null elements.

d) It is backed by a List.

2. How does HashSet handle duplicates when you try to add an element?

a) It throws an exception.

b) It adds the duplicate element and prints a warning.

c) It simply ignores the duplicate element.

d) It updates the existing element with the new value.

3. What is the time complexity of the add() method in a HashSet in the average case?

a) O(n)

b) O(log n)

c) O(1)

d) O(n log n)

4. Which of the following is true about HashSet compared to TreeSet?

a) HashSet stores elements in a sorted order, while TreeSet does not.

b) HashSet provides faster performance for large datasets.

c) TreeSet allows duplicate elements, while HashSet does not.

d) TreeSet is unordered, while HashSet maintains the insertion order.

5. Which method is used to remove an element from a HashSet?

a) remove()

b) delete()

c) discard()

d) erase()

6. What does the contains() method in HashSet return?

a) It returns false if the element is not found.

b) It returns true if the element is found, and false otherwise.

c) It throws an exception if the element is not found.

d) It returns null if the element is found.

7. What is the internal data structure used by HashSet to store elements?

a) ArrayList

b) TreeMap

c) HashMap

d) LinkedList

8. How can you iterate through the elements of a HashSet?

a) Using a for-each loop or an Iterator.

b) Using a while loop only.

c) Using a for loop with an index.

d) You cannot iterate through a HashSet.

9. When is it best to use a HashSet in Java?

a) When you need to store elements in a sorted order.

b) When you need to preserve the insertion order of elements.

c) When you need fast lookup and unique elements.

d) When you want to store elements with duplicates.

10. Which of the following statements is true about HashSet in Java?

a) HashSet allows duplicate elements but only in different positions.

b) The order of elements in HashSet is predictable and follows insertion order.

c) HashSet uses a hash table for storage, which allows for fast operations.

d) HashSet guarantees that the order of elements will always be ascending.

This quiz ensures you have a solid understanding of HashSet in Java, its features, operations, and when to use it effectively in your applications.

Also Read: Top 8 Reasons Why Java Is So Popular and Widely Used in 2025

You can continue expanding your skills in Java with upGrad, which will help you deepen your understanding of advanced Java concepts and real-world applications.

upGrad’s courses offer expert training in Java programming, with a focus on Java HashSet operations, best practices, and performance optimization. Gain hands-on experience in working with collections, efficiently managing unique elements, and building high-performance Java applications.

Below are some relevant upGrad courses:

You can also get personalized career counseling with upGrad to guide your career path, or visit your nearest upGrad center and start hands-on training today! 

Similar Reads:

FAQs

Q: Can a HashSet in Java store multiple null values?

A: No, a HashSet can only store one null value. If you try to add more than one null, only the first null will be stored.

Q: Why does HashSet not preserve the order of elements?

A: The elements in HashSet are stored based on their hash codes and do not maintain any specific order, unlike LinkedHashSet or TreeSet, which preserve insertion order or sorting, respectively.

Q: How do you ensure HashSet performs optimally when adding a large number of elements?

A: To optimize HashSet performance, it’s a good practice to initialize it with an appropriate initial capacity and load factor, which reduces resizing operations during frequent additions.

Q: What happens if you modify an element in HashSet after adding it?

A: HashSet uses the hash code of elements to store them. If you modify an element (e.g., changing its field that affects its hash code), it may not be correctly located within the set, leading to unexpected behavior.

Q: Is HashSet thread-safe? Can it be used in a multi-threaded environment?

A: By default, HashSet is not thread-safe. To make it thread-safe, you can either use Collections.synchronizedSet(new HashSet<>) or use a concurrent collection like CopyOnWriteArraySet for specific use cases.

Q: How can you check if HashSet contains any common elements with another collection?

A: You can use the retainAll() method to retain only the elements that are common between two collections. It modifies the HashSet to include only the common elements.

Q: What is the effect of increasing the load factor in HashSet?

A: A higher load factor increases the chance of fewer rehashing operations, but it also increases the time complexity for insertion and retrieval. A load factor of 0.75 is typically recommended as a balance between space and performance.

Q: What happens when two elements have the same hash code in a HashSet?

A: When two elements have the same hash code, HashSet uses separate chaining (linked lists or trees) to store the elements in the same bucket, avoiding collision but still ensuring uniqueness.

Q: Can you use custom objects as elements in HashSet? If so, how?

A: Yes, you can store custom objects in a HashSet, but you need to override the equals() and hashCode() methods in your class to ensure proper handling of equality and hash-based storage.

Q: How does HashSet handle large-scale data, and what makes it a good choice for such use cases?

A: HashSet is ideal for large datasets because of its O(1) average time complexity for add(), remove(), and contains() operations, making it faster than other collections like ArrayList for checking membership or removing elements.

Q: How can I convert a HashSet back into a List or an Array?

A: You can easily convert a HashSet to a List using the ArrayList constructor:

List<String> list = new ArrayList<>(hashSet);

For converting to an Array, use the toArray() method:

String[] array = hashSet.toArray(new String[0]);

Both methods help you transform the HashSet into a different collection type.

image

Take the Free Quiz on Java

Answer quick questions and assess your Java knowledge

right-top-arrow
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
advertise-arrow

Free Courses

Explore Our Free Software Tutorials

upGrad Learner Support

Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918045604032

Disclaimer

1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.

2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.