The Set interface in Java is part of the Java Collections Framework and represents a collection that doesn’t allow duplicate elements. It models the mathematical set abstraction, and it extends the Collection
interface.
Here’s a breakdown of the Set
interface and its common implementations:
- Unique Elements: A
Set
does not allow duplicates. If you try to add an element that already exists in the set, it won’t be added again. - Unordered by Nature: Elements in a
Set
are not guaranteed to be in any specific order, though some implementations (likeTreeSet
) do provide ordering. - Null Values: Most implementations allow a single null value, though this depends on the implementation (e.g.,
TreeSet
doesn’t allow nulls as it relies on comparisons).
- Description:
HashSet
is the most common implementation of theSet
interface. It uses a hash table to store elements, meaning it is unordered and unsorted. HashSet relies on a hash table structure through HashMap, it does not extend or use the Hashtable class itself. This approach lets HashSet manage unique elements efficiently using HashMap’s internal hash-based structure. - Performance:
HashSet
provides constant time performance (O(1)) for basic operations likeadd
,remove
, andcontains
, assuming a good hash function. - Null Values: Allows one null element.
- Usage: Ideal for applications where quick lookup and insertion are required, and ordering of elements is not a concern.
Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Cherry");
- Description:
LinkedHashSet
is a subclass ofHashSet
that maintains a linked list of the entries in the set. This preserves the insertion order of elements. - Performance: Slightly slower than
HashSet
due to the additional cost of maintaining the linked list, but it still provides constant-time performance (O(1)) for operations likeadd
,remove
, andcontains
. - Null Values: Allows one null element.
- Usage: Useful when you need predictable iteration order while also needing fast access and insertion.
Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
linkedHashSet.add("Cherry");
- Description:
TreeSet
is a set implementation that uses a Red-Black tree structure to store elements in a sorted order (natural ordering or by a specified comparator). - Performance: Operations like
add
,remove
, andcontains
are O(log n) due to the tree structure. - Null Values: Does not allow null values, as it relies on comparisons.
- Usage: Ideal for applications that need elements to be in a sorted order.
Set<String> treeSet = new TreeSet<>();
treeSet.add("Apple");
treeSet.add("Banana");
treeSet.add("Cherry");
- Description: A specialized set for enum types only. It’s highly efficient as it uses bitwise operations to manage enum values.
- Performance: Very fast operations (O(1)), as it is specifically designed for enums.
- Null Values: Does not allow null elements.
- Usage: Ideal when you need to store constants of a single enum type.
enum Days { MONDAY, TUESDAY, WEDNESDAY }
Set<Days> enumSet = EnumSet.of(Days.MONDAY, Days.WEDNESDAY);
- Description: A thread-safe version of
Set
backed by aCopyOnWriteArrayList
. It creates a copy of the underlying array on every modification. - Performance: Performs well for read-heavy operations, but write operations are costly due to array copying.
- Null Values: Allows null values.
- Usage: Useful in concurrent environments where reads are more frequent than modifications.
Set<String> copyOnWriteSet = new CopyOnWriteArraySet<>();
copyOnWriteSet.add("Apple");
copyOnWriteSet.add("Banana");
Implementation | Ordering | Performance (Add/Remove/Contains) | Nulls | Thread-Safe |
---|---|---|---|---|
HashSet | Unordered | O(1) | Yes | No |
LinkedHashSet | Insertion Order | O(1) | Yes | No |
TreeSet | Sorted Order | O(log n) | No | No |
EnumSet | Enum’s natural order | O(1) | No | No |
CopyOnWriteArraySet | Unordered | O(n) for add, O(1) for read | Yes | Yes |
- Use
HashSet
if you don’t care about the order of elements and need fast performance for insertions and lookups. - Use
LinkedHashSet
if you need to maintain the order in which elements are added. - Use
TreeSet
if you need a sorted set or want to traverse elements in a natural or custom order. - Use
EnumSet
when you have a set of constants from an enum type—it’s the most memory-efficient option. - Use
CopyOnWriteArraySet
in concurrent applications where reads vastly outnumber writes, as it offers thread-safe access without locking.
Each implementation serves a specific use case, so choosing the right one depends on whether you need order, performance, sorting, or thread safety.