Java HashSet
High-performance Set implementation using hash table
⚡ What is HashSet?
HashSet is the most popular Set implementation that uses hash table for storage, providing constant-time performance for basic operations like add, remove, and contains.
// Creating and using HashSet
import java.util.HashSet;
HashSet<String> cities = new HashSet<>();
cities.add("New York");
cities.add("London");
cities.add("Tokyo");
cities.add("New York"); // Duplicate ignored
System.out.println(cities);
System.out.println("Contains London: " + cities.contains("London"));
Output:
[Tokyo, New York, London]
Contains London: true
HashSet Advantages
Fast Operations
O(1) average time for add, remove, contains
set.contains("item"); // Very fast
Unique Elements
Automatically handles duplicates
set.add("duplicate"); // Ignored if exists
Memory Efficient
Efficient storage using hash table
// Optimized internal structure
No Ordering
Elements stored in hash order
// Order not guaranteed
🔹 Creating HashSet
Different ways to create and initialize HashSet:
import java.util.*;
public class HashSetCreation {
public static void main(String[] args) {
// 1. Empty HashSet
HashSet<String> set1 = new HashSet<>();
// 2. HashSet with initial capacity
HashSet<String> set2 = new HashSet<>(20);
// 3. HashSet with initial capacity and load factor
HashSet<String> set3 = new HashSet<>(20, 0.8f);
// 4. HashSet from another collection
List<String> list = Arrays.asList("A", "B", "C", "A");
HashSet<String> set4 = new HashSet<>(list);
// 5. Using Set interface (recommended)
Set<String> set5 = new HashSet<>();
// 6. Initialize with values (Java 9+)
Set<String> set6 = new HashSet<>(Set.of("X", "Y", "Z"));
// 7. Using Collections utility
Set<String> set7 = new HashSet<>();
Collections.addAll(set7, "P", "Q", "R");
System.out.println("Set4 (from list with duplicates): " + set4);
System.out.println("Set6 (initialized): " + set6);
System.out.println("Set7 (using Collections.addAll): " + set7);
}
}
Output:
Set4 (from list with duplicates): [A, B, C]
Set6 (initialized): [X, Y, Z]
Set7 (using Collections.addAll): [P, Q, R]
🔹 HashSet Methods
Essential HashSet operations with examples:
import java.util.*;
public class HashSetMethods {
public static void main(String[] args) {
HashSet<Integer> numbers = new HashSet<>();
// Adding elements
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(20); // Duplicate - ignored
System.out.println("After adding: " + numbers);
System.out.println("Size: " + numbers.size());
// Checking elements
System.out.println("Contains 20: " + numbers.contains(20));
System.out.println("Contains 40: " + numbers.contains(40));
System.out.println("Is empty: " + numbers.isEmpty());
// Adding multiple elements
numbers.addAll(Arrays.asList(40, 50, 30)); // 30 is duplicate
System.out.println("After addAll: " + numbers);
// Removing elements
boolean removed = numbers.remove(20);
System.out.println("Removed 20: " + removed);
System.out.println("After removal: " + numbers);
// Remove multiple elements
numbers.removeAll(Arrays.asList(40, 50));
System.out.println("After removeAll: " + numbers);
// Keep only specific elements
HashSet<Integer> toKeep = new HashSet<>(Arrays.asList(10, 30, 60));
numbers.retainAll(toKeep);
System.out.println("After retainAll: " + numbers);
// Clear all elements
HashSet<Integer> copy = new HashSet<>(numbers);
copy.clear();
System.out.println("After clear: " + copy);
System.out.println("Original: " + numbers);
}
}
Output:
After adding: [20, 10, 30]
Size: 3
Contains 20: true
Contains 40: false
Is empty: false
After addAll: [50, 20, 40, 10, 30]
Removed 20: true
After removal: [50, 40, 10, 30]
After removeAll: [10, 30]
After retainAll: [10, 30]
After clear: []
Original: [10, 30]
🔹 HashSet Performance
Understanding HashSet's performance characteristics:
Time Complexity:
- add(element): O(1) average, O(n) worst case
- remove(element): O(1) average, O(n) worst case
- contains(element): O(1) average, O(n) worst case
- size(): O(1)
- isEmpty(): O(1)
Space Complexity:
- Storage: O(n) where n is number of elements
- Load Factor: Default 0.75 (75% capacity before resize)
// Performance demonstration
HashSet<String> largeSet = new HashSet<>();
// Adding 1 million elements - still fast!
for (int i = 0; i < 1000000; i++) {
largeSet.add("Element" + i);
}
// Fast lookup even in large set
long startTime = System.nanoTime();
boolean found = largeSet.contains("Element500000");
long endTime = System.nanoTime();
System.out.println("Found: " + found);
System.out.println("Search time: " + (endTime - startTime) + " nanoseconds");
System.out.println("Set size: " + largeSet.size());
🔹 HashSet vs Other Collections
When to choose HashSet over other collections:
Choose HashSet when:
- You need to ensure unique elements
- Fast lookup/membership testing is important
- You don't need elements in any specific order
- You frequently check if elements exist
Don't choose HashSet when:
- You need elements in insertion order (use LinkedHashSet)
- You need elements sorted (use TreeSet)
- You need indexed access (use ArrayList)
- You allow duplicate elements (use List)
🔹 Practical HashSet Examples
Real-world applications of HashSet:
import java.util.*;
public class HashSetExamples {
public static void main(String[] args) {
// Example 1: Track unique visitors
HashSet<String> uniqueVisitors = new HashSet<>();
String[] visitors = {"user1", "user2", "user1", "user3", "user2", "user4"};
for (String visitor : visitors) {
if (uniqueVisitors.add(visitor)) {
System.out.println("New visitor: " + visitor);
} else {
System.out.println("Returning visitor: " + visitor);
}
}
System.out.println("Total unique visitors: " + uniqueVisitors.size());
// Example 2: Find unique words in text
String text = "the quick brown fox jumps over the lazy dog the fox is quick";
String[] words = text.split(" ");
HashSet<String> uniqueWords = new HashSet<>(Arrays.asList(words));
System.out.println("Original words: " + words.length);
System.out.println("Unique words: " + uniqueWords.size());
System.out.println("Unique word list: " + uniqueWords);
// Example 3: Check permissions
HashSet<String> userPermissions = new HashSet<>(
Arrays.asList("read", "write", "delete")
);
String[] requestedActions = {"read", "write", "execute", "delete"};
for (String action : requestedActions) {
if (userPermissions.contains(action)) {
System.out.println("✅ Permission granted for: " + action);
} else {
System.out.println("❌ Permission denied for: " + action);
}
}
}
}
Output:
New visitor: user1
New visitor: user2
Returning visitor: user1
New visitor: user3
Returning visitor: user2
New visitor: user4
Total unique visitors: 4
Original words: 13
Unique words: 9
Unique word list: [over, fox, dog, the, lazy, brown, is, quick, jumps]
✅ Permission granted for: read
✅ Permission granted for: write
❌ Permission denied for: execute
✅ Permission granted for: delete