The Set Interface
The Set interface extends the Collection interface. It represents an unordered collection of elements that does not allow duplicate elements. It is essentially a programmatic implementation of the mathematical set abstraction.
The most commonly used implementations of the Set interface are HashSet, LinkedHashSet, and TreeSet.
1. HashSet
The HashSet class is the default, go-to implementation of the Set interface. It stores its elements in a hash table (specifically, it is backed by a HashMap under the hood).
Key Characteristics
- No Duplicates: If you try to add a duplicate element, the
add()method will simply returnfalseand the set will not change. - Unordered: It makes no guarantees about the iteration order of the set. The order may change over time as elements are added and removed.
- Fast Performance: It offers constant time performance $O(1)$ for basic operations (
add,remove,contains), assuming the hash function disperses elements properly. - Allows Null: It allows a single
nullelement.
Example
import java.util.HashSet;
import java.util.Set;
public class LabSet1 {
public static void main(String args[]) {
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Orange");
// Attempting to add a duplicate
boolean isAdded = set.add("Apple");
System.out.println("Was duplicate added? " + isAdded); // false
// The order of output is unpredictable!
for (String fruit : set) {
System.out.println(fruit);
}
}
}
2. LinkedHashSet
The LinkedHashSet class extends HashSet. It maintains a doubly-linked list running through all of its entries.
Key Characteristics
- Predictable Iteration Order: Unlike
HashSet, it maintains insertion order. When you iterate through aLinkedHashSet, elements will be returned in the exact order they were inserted. - Slightly Slower: Because it has to maintain the linked list, it has slightly higher memory overhead and is marginally slower than
HashSetfor insertions and deletions.
import java.util.LinkedHashSet;
import java.util.Set;
public class LabSet2 {
public static void main(String args[]) {
Set<String> set = new LinkedHashSet<>();
set.add("One");
set.add("Two");
set.add("Three");
// Order is guaranteed to be: One, Two, Three
System.out.println(set);
}
}
3. TreeSet
The TreeSet class implements the SortedSet interface (which extends Set). It uses a Red-Black tree structure under the hood.
Key Characteristics
- Sorted Order: It stores elements in their natural ascending order (e.g., A-Z for Strings, 1-9 for Integers), or according to a custom
Comparatorprovided at creation time. - Slower Performance: Because it has to sort elements upon insertion, basic operations take $O(\log n)$ time.
- No Nulls: Unlike
HashSet,TreeSetdoes not allownullelements (it will throw aNullPointerExceptionif you try to add one).
Example
import java.util.Set;
import java.util.TreeSet;
public class LabSet3 {
public static void main(String args[]) {
Set<Integer> numbers = new TreeSet<>();
// Inserting in random order
numbers.add(50);
numbers.add(10);
numbers.add(30);
// The output will be automatically sorted: [10, 30, 50]
System.out.println("Sorted Set: " + numbers);
}
}
[!TIP] Summary: When to use what?
- Need maximum performance and don't care about order? Use
HashSet.- Need to maintain insertion order? Use
LinkedHashSet.- Need elements to be automatically sorted? Use
TreeSet.