Set Interface
The Set interface is part of the Java Collections Framework and represents a collection that does not allow duplicate elements. It models the concept of a mathematical set, ensuring uniqueness of elements. This is a high-frequency interview topic, often compared with List.
What Is the Set Interface?
- A collection that does not allow duplicates
- No index-based access
- Order depends on implementation
- Allows at most one null (implementation-dependent)
- Part of java.util package
Set<String> set = new HashSet<>();
Position in Collection Hierarchy
Iterable
└── Collection
└── Set
├── HashSet
├── LinkedHashSet
└── TreeSet
Key Characteristics of Set
- No duplicate elements
- Equality based on equals() and hashCode()
- No positional (index) access
- Designed for uniqueness and fast lookup
Common Implementations of Set
1️⃣ HashSet
- Backed by hash table
- Unordered (no guarantee of order)
- Fast performance (O(1) average)
- Allows one null
Set<Integer> set = new HashSet<>();
2️⃣ LinkedHashSet
- Maintains insertion order
- Slightly slower than HashSet
- Allows one null
Set<Integer> set = new LinkedHashSet<>();
3️⃣ TreeSet
- Stores elements in sorted order
- Based on Red-Black Tree
- Does not allow null
- Slower (O(log n) operations)
Set<Integer> set = new TreeSet<>();
Important Methods of Set Interface
set.add("Java");
set.remove("Java");
set.contains("Java");
set.size();
set.isEmpty();
- ✔ No get(index)
- ✔ No positional methods
Duplicate Handling Example
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Java");
System.out.println(set); // [Java]
- ✔ Duplicate ignored
- ✔ No exception thrown
How Set Ensures Uniqueness (Interview Favorite)
- Uses hashCode() to find bucket
- Uses equals() to check equality
class Employee {
int id;
}
⚠️ If equals() and hashCode() are not overridden properly, duplicates may occur logically.
Set vs List (Interview Comparison)
| Aspect | Set | List |
|---|---|---|
| Duplicates | ❌ Not allowed | ✅ Allowed |
| Order | Depends on implementation | Preserved |
| Index access | ❌ No | ✅ Yes |
| Use case | Unique data | Ordered data |
Performance Complexity
| Implementation | Add / Remove / Search |
|---|---|
| HashSet | O(1) average |
| LinkedHashSet | O(1) |
| TreeSet | O(log n) |
Iterating a Set
for (String s : set) {
System.out.println(s);
}
or
Iterator<String> it = set.iterator();
When to Use Set
- When uniqueness is required
- Removing duplicates
- Membership checking
- Mathematical set operations
When NOT to Use Set
- When duplicates are needed
- When index-based access is required
- When strict insertion order is mandatory (unless LinkedHashSet)
Common Beginner Mistakes
- Expecting insertion order in HashSet
- Using mutable objects as keys without proper equals() / hashCode()
- Trying to access elements by index
- Using TreeSet with null values
Interview-Ready Answers
Short Answer
The Set interface represents a collection that does not allow duplicate elements.
Detailed Answer
In Java, the Set interface extends the Collection interface and models a mathematical set. It ensures uniqueness of elements and provides implementations such as HashSet, LinkedHashSet, and TreeSet, each with different ordering and performance characteristics.
Set Interface Examples
1. Creating a Set Using HashSet
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Java");
set.add("API");
set.add("Java"); // duplicate
System.out.println(set);
}
}
Output
[Java, API]
2. Set Does Not Allow Duplicates
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(10);
set.add(10);
System.out.println(set.size());
}
}
Output
1
3. HashSet Does NOT Maintain Insertion Order
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("B");
set.add("A");
set.add("C");
System.out.println(set);
}
}
Output
[A, B, C] // order may vary
4. LinkedHashSet – Maintains Insertion Order
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<>();
set.add("B");
set.add("A");
set.add("C");
System.out.println(set);
}
}
Output
[B, A, C]
5. TreeSet – Sorted Set
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
set.add(30);
set.add(10);
set.add(20);
System.out.println(set);
}
}
Output
[10, 20, 30]
6. TreeSet Does NOT Allow null
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
// set.add(null); // ❌ NullPointerException
}
}
7. HashSet Allows One null
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add(null);
set.add(null);
System.out.println(set);
}
}
Output
[null]
8. Iterating Set Using for-each
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = new HashSet<>(Arrays.asList("A", "B", "C"));
for (String s : set) {
System.out.println(s);
}
}
}
9. Iterating Set Using Iterator
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3));
Iterator<Integer> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
10. Removing Element While Iterating (Safe Way)
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3));
Iterator<Integer> it = set.iterator();
while (it.hasNext()) {
if (it.next() == 2) {
it.remove();
}
}
System.out.println(set);
}
}
Output
[1, 3]
11. Checking Element Existence
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = new HashSet<>(Arrays.asList("Java", "API"));
System.out.println(set.contains("Java"));
}
}
Output
true
12. Converting List to Set (Remove Duplicates)
import java.util.*;
class Demo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 2, 3);
Set<Integer> set = new HashSet<>(list);
System.out.println(set);
}
}
Output
[1, 2, 3]
13. Custom Objects in HashSet (equals & hashCode)
class User {
int id;
User(int id) { this.id = id; }
public boolean equals(Object o) {
return this.id == ((User)o).id;
}
public int hashCode() {
return id;
}
}
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<User> set = new HashSet<>();
set.add(new User(1));
set.add(new User(1));
System.out.println(set.size());
}
}
Output
1
14. TreeSet with Custom Sorting
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = new TreeSet<>((a, b) -> b.compareTo(a));
set.add("A");
set.add("C");
set.add("B");
System.out.println(set);
}
}
Output
[C, B, A]
15. Set.of() (Immutable Set – Java 9+)
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = Set.of("A", "B");
System.out.println(set);
// set.add("C"); // ❌ UnsupportedOperationException
}
}
16. retainAll() – Intersection
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<Integer> s1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> s2 = new HashSet<>(Arrays.asList(2, 3, 4));
s1.retainAll(s2);
System.out.println(s1);
}
}
Output
[2, 3]
17. removeAll() – Difference
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<Integer> s1 = new HashSet<>(Arrays.asList(1, 2, 3));
Set<Integer> s2 = new HashSet<>(Arrays.asList(2));
s1.removeAll(s2);
System.out.println(s1);
}
}
Output
[1, 3]
18. addAll() – Union
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<Integer> s1 = new HashSet<>(Arrays.asList(1, 2));
Set<Integer> s2 = new HashSet<>(Arrays.asList(2, 3));
s1.addAll(s2);
System.out.println(s1);
}
}
Output
[1, 2, 3]
19. Thread-Safe Set
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = Collections.synchronizedSet(new HashSet<>());
set.add("Safe");
System.out.println(set);
}
}
20. Interview Summary – Set Interface
import java.util.*;
class Demo {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Unique");
set.add("Unique");
System.out.println(set);
}
}
Key Points
- No duplicates
- No index-based access
- HashSet → fast, unordered
- LinkedHashSet → insertion order
- TreeSet → sorted
Key Takeaway
Use Set when uniqueness matters. Choose the right implementation (HashSet, LinkedHashSet, or TreeSet) based on ordering and performance needs.