More specifically: how to get the nth element of a LinkedHashSet (which has a predictable iteration order)? I want to retrieve the nth element inserted into this Set
(which wasn't already present).
Is it better to use a List
:
List<T> list = new ArrayList<T>(mySet);
T value = list.get(x); // x < mySet.size()
or the toArray(T [] a)
method:
T [] array = mySet.toArray(new T[mySet.size()]);
T value = array[y]; // y < mySet.size()
Other than the (likely slight) performance differences, anything to watch out for? Any clear winner?
NB: It doesn't matter why I want the last-inserted element, all that matters is that I want it. LinkedHashSet was specifically chosen because it "defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set."
This question seems to have devolved into a discussion of whether any Set
implementation can ever preserve original insertion order. So I put up some simple test code at http://pastebin.com/KZJ3ETx9 to show that yes, LinkedHashSet does indeed preserve insertion order (the same as its iteration order) as its Javadoc claims.
Modified the description of the problem so that everybody isn't too focused on retrieving the last element of the Set
(I originally thought that the title of the question would be enough of a hint — obviously I was wrong).
So I decided to go with a slight variation of the answer by @Juvanis.
To get at the nth element in a LinkedHashSet:
Iterator<T> itr = mySet.iterator();
int nth = y;
T value = null;
for(int i = 0; itr.hasNext(); i++) {
value = itr.next();
if (i == nth) {
break;
}
}
Version 2 of the code:
public class SetUtil {
@Nullable
public static <T> T nthElement(Set<T> set, int n) {
if (null != set && n >= 0 && n < set.size()) {
int count = 0;
for (T element : set) {
if (n == count)
return element;
count++;
}
}
return null;
}
}
NB: with some slight modifications the method above can be used for all Iterables<T>
.
This avoids the overhead of ensuring that a Set
and a List
stay in sync, and also avoids having to create a new List
every time (which will be more time-consuming than any amount of algorithmic complexity).
Obviously I am using a Set
to ensure uniqueness and I'd rather avoid a lengthy explanation as to why I need indexed access.