← Back to Home

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.