I have the following kind of situation:
Set<Element> set = getSetFromSomewhere();
if (set.size() == 1) {
// return the only element
} else {
throw new Exception("Something is not right..");
}
Assuming I cannot change the return type of getSetFromSomewhere()
, is there a better or more correct way to return the only element in the set than
- Iterating over the set and returning immediately
- Creating a list from the set and calling
.get(0)
You could grab the iterator:
The best general solution (where you don't know the actual set class) is:
If the set class is known to be a
SortedSet
(e.g. aTreeSet
orConcurrentSkipListSet
), then a better solution is:In both cases, an exception will be thrown if the set is empty; check the javadocs. The exception can be avoided using
Collection.isEmpty()
.The first solution is
O(1)
in time and space for aHashSet
orLinkedHashSet
, but typically worse for other kinds of set.The second one is
O(logN)
in time , and uses no space forTreeSet
orConcurrentSkipListSet
.The approach of creating a list from the set contents and then calling
List.get(0)
gives a poor solution since the first step is anO(N)
operation, both in time and space.I failed to notice that
N
is actually1
. But even so, creating an iterator is likely to be less expensive than creating a temporary list.You can use an
Iterator
to both obtain the only element as well as verify that the collection only contains one element (thereby avoiding thesize()
call and the unnecessary list creation):You would typically wrap this up in its own method:
Note that this implementation is already part of Google's Guava libraries (which I highly recommend, even if you don't use it for this particular code). More specifically, the method belongs to the
Iterables
class:If you're curious about how it is implemented, you can look at the
Iterators
class source code (the methods inIterables
often call methods inIterators
):