The Set
interface in Java is part of the Java Collections Framework and represents a collection that does not allow duplicate elements. A Set
can contain at most one null element.
Common Methods
add(E e)
: Adds the specified element to the set if it is not already present
boolean addAll(Collection<? extends E> c)
: Adds all of the elements in the specified collection to the set if they’re not already present.
boolean remove(Object o)
: Removes the specified element from the set if it is present.
boolean removeAll(Collection<?> c)
: Removes from this set all of its elements that are contained in the specified collection.
void clear()
: Removes all of the elements from the set.
boolean contains(Object o)
: Returns true
if the set contains the specified element.
boolean containsAll(Collection<?> c)
: Returns true
if the set contains all of the elements in the specified collection
int size()
: Returns the number of elements in the set
boolean isEmpty()
: Returns true
if the set contains no elements
void forEach(Consumer<? super E> action)
: Performs the given action for each element of the set.
boolean retainAll(Collection<?> c)
: Retains only the elements in this set that are contained in the specified collection.
Object[] toArray()
: Returns an array containing all of the elements in the set.
Implementation Classes
- HashSet:
HashSet
is backed by a hash table (an instance ofHashMap
). It does not maintain any order of elements. The iteration order is not guaranteed and can change over time. Provides constant-time performance for basic operations like add, remove, and contains. It permits the null element. Usecase: When the uniqueness of elements is required without caring about the order. - LinkedHashSet:
LinkedHashSet
extendsHashSet
and maintains a doubly-linked list across all elements. It maintains the insertion order of elements. Elements are returned in the order they were inserted. Performance is slightly slower thanHashSet
due to the overhead of maintaining the linked list. Usecase: when the uniqueness of elements is required, and the order of insertion needs to be preserved. Suitable for scenarios where both quick lookups and ordered iteration are required. - TreeSet: It implements the
NavigableSet
interface. It is backed by a Red-Black tree, a self-balancing binary search tree. Maintains elements in sorted (ascending) order. Does not allow null elements. Supports range operations and provides methods like subSet, headSet, and tailSet. Usecase: When a sorted set of elements and their iteration is required. When range view operations are needed.
HashSet
HashSet is implemented using a hash table (specifically, an instance of HashMap). It does not allow duplicate elements. Adding a duplicate element does not change the set. HashSet does not maintain any order of elements. The order can change over time.
import java.util.HashSet;
import java.util.Iterator;
public class HashSetExample {
public static void main(String[] args) {
// Creating a HashSet
HashSet<String> hashSet = new HashSet<>();
// Adding elements
hashSet.add("Alice");
hashSet.add("Bob");
hashSet.add("Charlie");
System.out.println("HashSet after adding elements: " + hashSet);
// Adding duplicate element
boolean addedDuplicate = hashSet.add("Alice");
System.out.println("Was 'Alice' added again? " + addedDuplicate); // false, 'Alice' already exists
// Adding elements from another collection
HashSet<String> anotherSet = new HashSet<>();
anotherSet.add("Dave");
anotherSet.add("Eve");
hashSet.addAll(anotherSet);
System.out.println("HashSet after adding elements from anotherSet: " + hashSet);
// Removing elements
hashSet.remove("Bob");
System.out.println("HashSet after removing 'Bob': " + hashSet);
// Removing all elements in another collection
hashSet.removeAll(anotherSet);
System.out.println("HashSet after removing all elements in anotherSet: " + hashSet);
// Checking if set contains an element
boolean containsCharlie = hashSet.contains("Charlie");
System.out.println("Does HashSet contain 'Charlie'? " + containsCharlie);
// Checking if set is empty
boolean isEmpty = hashSet.isEmpty();
System.out.println("Is HashSet empty? " + isEmpty);
// Getting size of the set
int size = hashSet.size();
System.out.println("Size of HashSet: " + size);
// Iterating over elements using Iterator
System.out.println("Iterating over HashSet elements:");
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// Converting HashSet to array
Object[] array = hashSet.toArray();
System.out.println("HashSet elements as array:");
for (Object obj : array) {
System.out.println(obj);
}
// Clearing the set
hashSet.clear();
System.out.println("HashSet after clearing: " + hashSet);
}
}
LinkedHashSet
LinkedHashSet is implemented as a hash table with a predictable iteration order maintained by a linked list. It does not allow duplicate elements. Adding a duplicate element does not change the set. LinkedHashSet maintains the order of insertion of elements. Elements are returned in the order they were inserted. Allows a single null element.
import java.util.LinkedHashSet;
import java.util.Iterator;
public class LinkedHashSetExample {
public static void main(String[] args) {
// Creating a LinkedHashSet
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
// Adding elements
linkedHashSet.add("Alice");
linkedHashSet.add("Bob");
linkedHashSet.add("Charlie");
System.out.println("LinkedHashSet after adding elements: " + linkedHashSet);
// Adding duplicate element
boolean addedDuplicate = linkedHashSet.add("Alice");
System.out.println("Was 'Alice' added again? " + addedDuplicate); // false, 'Alice' already exists
// Adding elements from another collection
LinkedHashSet<String> anotherSet = new LinkedHashSet<>();
anotherSet.add("Dave");
anotherSet.add("Eve");
linkedHashSet.addAll(anotherSet);
System.out.println("LinkedHashSet after adding elements from anotherSet: " + linkedHashSet);
// Removing elements
linkedHashSet.remove("Bob");
System.out.println("LinkedHashSet after removing 'Bob': " + linkedHashSet);
// Removing all elements in another collection
linkedHashSet.removeAll(anotherSet);
System.out.println("LinkedHashSet after removing all elements in anotherSet: " + linkedHashSet);
// Checking if set contains an element
boolean containsCharlie = linkedHashSet.contains("Charlie");
System.out.println("Does LinkedHashSet contain 'Charlie'? " + containsCharlie);
// Checking if set is empty
boolean isEmpty = linkedHashSet.isEmpty();
System.out.println("Is LinkedHashSet empty? " + isEmpty);
// Getting size of the set
int size = linkedHashSet.size();
System.out.println("Size of LinkedHashSet: " + size);
// Iterating over elements using Iterator
System.out.println("Iterating over LinkedHashSet elements:");
Iterator<String> iterator = linkedHashSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// Converting LinkedHashSet to array
Object[] array = linkedHashSet.toArray();
System.out.println("LinkedHashSet elements as array:");
for (Object obj : array) {
System.out.println(obj);
}
// Clearing the set
linkedHashSet.clear();
System.out.println("LinkedHashSet after clearing: " + linkedHashSet);
}
}
TreeSet
TreeSet is implemented as a Red-Black tree, a type of self-balancing binary search tree. It does not allow duplicate elements. Adding a duplicate element does not change the set. TreeSet maintains elements in sorted (ascending) order. It does not allow null elements.
import java.util.TreeSet;
import java.util.Iterator;
public class TreeSetExample {
public static void main(String[] args) {
// Creating a TreeSet
TreeSet<String> treeSet = new TreeSet<>();
// Adding elements
treeSet.add("Alice");
treeSet.add("Bob");
treeSet.add("Charlie");
System.out.println("TreeSet after adding elements: " + treeSet);
// Adding duplicate element
boolean addedDuplicate = treeSet.add("Alice");
System.out.println("Was 'Alice' added again? " + addedDuplicate); // false, 'Alice' already exists
// Adding elements from another collection
TreeSet<String> anotherSet = new TreeSet<>();
anotherSet.add("Dave");
anotherSet.add("Eve");
treeSet.addAll(anotherSet);
System.out.println("TreeSet after adding elements from anotherSet: " + treeSet);
// Removing elements
treeSet.remove("Bob");
System.out.println("TreeSet after removing 'Bob': " + treeSet);
// Removing all elements in another collection
treeSet.removeAll(anotherSet);
System.out.println("TreeSet after removing all elements in anotherSet: " + treeSet);
// Checking if set contains an element
boolean containsCharlie = treeSet.contains("Charlie");
System.out.println("Does TreeSet contain 'Charlie'? " + containsCharlie);
// Checking if set is empty
boolean isEmpty = treeSet.isEmpty();
System.out.println("Is TreeSet empty? " + isEmpty);
// Getting size of the set
int size = treeSet.size();
System.out.println("Size of TreeSet: " + size);
// Iterating over elements using Iterator
System.out.println("Iterating over TreeSet elements:");
Iterator<String> iterator = treeSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// Converting TreeSet to array
Object[] array = treeSet.toArray();
System.out.println("TreeSet elements as array:");
for (Object obj : array) {
System.out.println(obj);
}
// Clearing the set
treeSet.clear();
System.out.println("TreeSet after clearing: " + treeSet);
}
}