Chapter 44 of 57

HashSet in Java

Sometimes we want to store a collection of values, but we don't want duplicate values.

For example, imagine you are storing the names of students who attended a class. If John is added twice, we probably don't want his name to appear twice.

This is where HashSet is useful.

A HashSet is a collection that stores unique elements. If you try to add the same value more than once, it simply keeps one copy.

Creating a HashSet

HashSet is part of the java.util package, so we first import it:

import java.util.HashSet;

Then we can create a HashSet:

HashSet<String> names = new HashSet<>();

Here, the String tells Java that the set will store String values.

We can add values using add():

names.add("John");
names.add("Jason");
names.add("Alex");

Now the set contains those three names.

Duplicate Values

The most important feature of a HashSet is that it does not allow duplicate elements.

For example:

HashSet<String> names = new HashSet<>();

names.add("John");
names.add("Jason");
names.add("John");
names.add("Alex");

Even though "John" was added twice, the HashSet stores it only once.

So the set contains:

John
Jason
Alex

The second "John" is simply ignored.

Checking for an Element

We can use the contains() method to check whether a value exists.

HashSet<String> names = new HashSet<>();

names.add("John");
names.add("Jason");

System.out.println(names.contains("John"));
System.out.println(names.contains("Alex"));

Output:

true
false

This is useful when we simply need to know whether an element is already present.

Removing an Element

We can remove an element using the remove() method:

names.remove("John");

After this, "John" is no longer in the set.

We can also check the number of elements using size():

System.out.println(names.size());

Just like ArrayList, HashSet uses size() rather than length.

Looping Through a HashSet

We can use an enhanced for loop to access the elements:

HashSet<String> names = new HashSet<>();

names.add("John");
names.add("Jason");
names.add("Alex");

for (String name : names) {
    System.out.println(name);
}

The important thing to notice is that you should not rely on the order in which elements come out of a HashSet.

For example, you might see:

Alex
John
Jason

The order is not guaranteed.

This is an important difference from a list, where elements have a defined index-based order.

HashSet Does Not Use Indexes

With an ArrayList, we can access an element using its index:

names.get(0);

A HashSet doesn't work this way.

There is no:

names.get(0); // Error

because a HashSet does not provide index-based access.

You generally interact with its elements using methods such as add(), remove(), contains(), and iteration.

HashSet with Numbers

A HashSet can store numbers as well.

Since collections use objects rather than primitive types, we use wrapper classes such as Integer:

HashSet<Integer> numbers = new HashSet<>();

numbers.add(10);
numbers.add(20);
numbers.add(10);
numbers.add(30);

The duplicate 10 will only be stored once.

The set contains the unique values:

10
20
30

HashSet vs ArrayList

The biggest difference is how they handle duplicates and ordering.

ArrayList

HashSet

Allows duplicates

Does not allow duplicates

Maintains index-based order

No guaranteed iteration order

Supports get(index)

No index-based access

Good when order and positions matter

Good when uniqueness matters

For example, if you want to store a student's marks in their original order, an ArrayList may be appropriate.

If you want to store unique usernames or unique IDs, a HashSet can be a better choice.

A Real-World Example

Imagine you are building a website where users can select their favorite programming languages.

A user might accidentally select Java twice.

Instead of manually checking for duplicates, we can use a HashSet:

HashSet<String> languages = new HashSet<>();

languages.add("Java");
languages.add("Python");
languages.add("Java");
languages.add("C++");

System.out.println(languages);

The duplicate "Java" is automatically ignored.

This makes HashSet very convenient when uniqueness is important.

A Complete Example

Let's create a simple program that stores unique student names:

import java.util.HashSet;

class Main {
    public static void main(String[] args) {

        HashSet<String> students = new HashSet<>();

        students.add("John");
        students.add("Jason");
        students.add("Alex");
        students.add("John");

        System.out.println("Number of students: " + students.size());

        for (String student : students) {
            System.out.println(student);
        }
    }
}

The output will contain each name only once, although "John" was added twice.

The main thing to remember is:

HashSet is a collection used when you want to store unique values and don't need index-based access or guaranteed iteration order.

If your main requirement is "don't allow duplicates," HashSet is one of the first collections you should think about.