Java Sets

Sameera De Silva
5 min readNov 5, 2023

--

Set Interface

Set interface is a part of the Java Collections Framework and is found in the java.util package.

It stores unique elements.
The order of the elements is not guaranteed.
Some common implementations of the Set interface include HashSet, TreeSet,SetAndHashSet and LinkedHashSet.
99
% time we use the HashSet so learn it a lot.

Here are some of the key features of the Set interface:

Uniqueness: The Set interface ensures that all elements are unique. If you try to add a duplicate element to a Set, it will be ignored.
Unordered: The Set interface does not guarantee the order of the elements. The elements may be returned in any order.
Dynamic: The Set interface is dynamic. You can add, remove, and iterate over elements in a Set.

Set<String> mySet = new HashSet<>();
mySet.add("hello");
mySet.add("world");
mySet.add("!");
for (String element : mySet) {
System.out.println(element);
}

Hashset

Implements Set Interface.
Cant’ remove values based on index.
The underlying data structure for HashSet is Hashtable.
As it implements the Set Interface, duplicate values are not allowed.
Objects that you insert in HashSet are not guaranteed to be inserted in the same order. Objects are inserted based on their hash code.
Only one NULL element is allowed in HashSet.
HashSet also implements Serializable and Cloneable interfaces.

Code

// Define a String HashSet
HashSet<String> names = new HashSet<>();

// Add elements to the HashSet
names.add("Alice");
names.add("Bob");
names.add("Charlie");
names.add("David");

// Print the size of the HashSet
System.out.println("Size of the HashSet: " + names.size());

// Check if an element exists
System.out.println("Does the HashSet contain 'Bob'? " + names.contains("Bob"));

// Check hash sets is empty or not.
if (names.isEmpty()) {
System.out.println("The HashSet is empty.");
}
// Find an element by value
System.out.println("The first element in the HashSet is: " + names.iterator().next());

// Remove an element
names.remove("Charlie");

// Iterate through the HashSet and print each element
for (String name : names) {
System.out.println(name);
}

// Empty the HashSet
names.clear();

// Check if the HashSet is empty
System.out.println("Is the HashSet empty? " + names.isEmpty());

// Sort the HashSet in ascending order using TreeSet
TreeSet<String> sortedNames = new TreeSet<>(names);
System.out.println("HashSet sorted in ascending order:");
for (String name : sortedNames) {
System.out.println(name);
}

// Sort the HashSet in descending order using a Comparator
Comparator<String> reverseComparator = Collections.reverseOrder();
TreeSet<String> descendingNames = new TreeSet<>(names, reverseComparator);
System.out.println("HashSet sorted in descending order:");
for (String name : descendingNames) {
System.out.println(name);
}

An exercise

HashSet check that Bob is there , if so change is name to Bryan and print a message as name is changed.

// Define a String HashSet
HashSet<String> names = new HashSet<>();

// Add elements to the HashSet
names.add("Alice");
names.add("Bob");
names.add("Charlie");
names.add("David");

// Check if "Bob" is in the HashSet
if (names.contains("Bob")) {
System.out.println("Name found: Bob");

// Change "Bob" to "Bryan"
names.remove("Bob");
names.add("Bryan");

System.out.println("Name changed: Bob -> Bryan");
} else {
System.out.println("Name not found: Bob");
}

How to compare Two HashSets are equal

Two HashSets are considered equal if they contain the same elements, regardless of the order of the elements.
To compare two HashSets for equality, you can use the equals() method of the HashSet class.
This method takes another HashSet object as an argument and returns true if the two sets are equal, and false otherwise.

HashSet<String> names1 = new HashSet<>();
names1.add("Alice");
names1.add("Bob");
names1.add("Charlie");

HashSet<String> names2 = new HashSet<>();
names2.add("Bob");
names2.add("Alice");
names2.add("Charlie");

if (names1.equals(names2)) {
System.out.println("The HashSets are equal.");
} else {
System.out.println("The HashSets are not equal.");
}

A real world scenario — To remove duplicates and store only unique values of a List

       // Create a LinkedList named 'names'
LinkedList<String> names = new LinkedList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
names.add("Bob"); // Add duplicate value "Bob"
names.add("Alice"); // Add duplicate value "Alice"

// Create a HashSet named 'uniqueNames'
HashSet<String> uniqueNames = new HashSet<>();

// Copy all elements from the 'names' LinkedList to the 'uniqueNames' HashSet
uniqueNames.addAll(names);
System.out.println(uniqueNames);
}
// A good video https://www.youtube.com/watch?v=QvHBHuuddYk&t=411s

Can I sort a Java Hastset?

No for that you have to use a TreeSet or a LinkedHashSet.

TreeSet

It’s still content the methods that HashSets have.

A Java TreeSet is a specialized Set implementation that maintains elements in sorted order, either by their natural ordering or a custom Comparator provided during creation. It provides efficient access to elements, supports set operations, and allows for navigation through the sorted set.

Drwaback over HashSet-

Java TreeSet is generally considered more memory-consuming than Java HashSet due to the additional data structures it maintains to ensure sorted order. (Natural order, not the order that inserted)

TreeSet utilizes a self-balancing binary search tree to keep elements in sorted order, which requires additional memory overhead compared to HashSet’s hash table implementation.
HashSet is faster than TreeSet

Note-

In a TreeSet, you cannot access elements using an index directly.

A TreeSet is designed to maintain elements in a sorted order and does not provide index-based access like you would find in a List implementation such as ArrayList

Set<String> treeSet = new TreeSet<>();
treeSet.add("Banana");
treeSet.add("Apple");
treeSet.add("Orange");
treeSet.add("PineApple");

for (String element : treeSet) {
System.out.println(element);
}

Output will be in narutal order , neither random or inserted order.

[Apple, Banana, Orange, PineApple]

If you want to have values ,based on inserted order use LinkedHashSet.

LinkedHashSet

It’s still content the methods that HashSets have.

The main feature is , it allows to maintain the inserted order.

A LinkedHashSet in Java is a class that implements the Set interface and extends HashSet. It combines the features of a HashSet with the ability to maintain the order of insertion. Here are some key features and characteristics of a LinkedHashSet:

Order Preservation: Unlike a regular HashSet, a LinkedHashSet maintains the order of elements in which they were inserted. When you iterate through a LinkedHashSet, the elements are presented in the order they were added.

Uniqueness: Like other Set implementations, a LinkedHashSet does not allow duplicate elements. It ensures that all elements are unique.

Null Values: A LinkedHashSet can store a single null value. If you attempt to add multiple null values, only one will be stored, as the set enforces uniqueness.

Fast Retrieval: LinkedHashSet provides fast retrieval of elements. It uses a combination of a hash table and a linked list to achieve this, resulting in efficient add, remove, and contains operations.

No Indexing: Similar to HashSet, LinkedHashSet does not support direct indexing like an array or a list. You can only access elements by their values, not by their positions.

import java.util.LinkedHashSet;

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

set.add("Apple");
set.add("Banana");
set.add("Orange");
set.add("Apple"); // Duplicate element, will not be added

System.out.println("Set size: " + set.size()); // Output: Set size: 3

for (String element : set) {
System.out.println(element);
}
}
}

--

--

Responses (1)