EnumSet.copyOf a non-EnumSet collection needs at least one element to infer its enum type; noneOf states the element class explicitly and works for an empty source.
Java EnumSet: retain element type when a source collection is empty
Operational contract
The helper starts with a typed empty EnumSet, then adds supplied review states. It returns an independent mutable set even when the source is empty. Duplicate states collapse by set semantics, and null elements are rejected. If the API promises an immutable result, wrap or copy it separately; returning EnumSet transfers mutation ownership to the caller. This lesson concerns type inference and collection ownership, not permission policy.
Failure case
An intake has no review flags. Building EnumSet.copyOf from an ordinary empty List throws because the enum type cannot be inferred. The typed empty set returns normally.
Java code
import java.util.Collection;
import java.util.EnumSet;
import java.util.Objects;
public class ReceiptReviewStates {
public enum State { NEW, CHECKED, HELD, RELEASED }
public static EnumSet<State> copy(Collection<State> states) {
Objects.requireNonNull(states);
EnumSet<State> result = EnumSet.noneOf(State.class);
result.addAll(states);
return result;
}
}Performance and ownership cost
Copying N source elements costs O(N) time and compact O(E) bit storage for E enum constants. It is a new set, so later mutation of the source does not change the result.
Common Mistakes
- Do not call EnumSet.copyOf on an ordinary empty collection and expect type inference.
- Do not assume the returned EnumSet is immutable.
- Do not silently accept null states; EnumSet rejects them.
Connected lessons
- Java EnumSet complementOf: derive a default-deny capability set
- Java collection factories: rejected updates and shallow element ownership
- List.copyOf freezes container membership but not mutable elements
- Java BitSet: distinguish logical length, capacity, and set-bit count
- Java BitSet nextSetBit: scan a bounded index range without walking gaps
- Java NavigableSet subSet: account for a live backed range
- Java specialized collections quiz
- Advanced Java
