LinkedHashSet
is not explicitly indexed per se. If you require an index, using a Set
for such application is usually a sign of wrong abstraction and/or lousy programming. LinkedHashSet
only guarantees you predictable iteration order, not proper indexing of elements. You should use a List
in such cases, since that's the interface giving you indexing guarantee. You can, however, infer the index using a couple of methods, for example (not recommended, mind me):
a) use indexed iteration through the collection (e.g. with for
loop), seeking the duplicate and breaking when it's found; it's O(n) complexity for getting the index,
Object o; // this is the object you want to add to collection
if ( !linkedHashSet.add(o) ) {
int index = 0;
for( Object obj : linkedHashSet ) {
if ( obj == o ) // or obj.equals(o), depending on your code's semantics
return index;
index++;
}
}
b) use .toArray()
and find the element in the array, e.g. by
Object o; // this is the object you want to add to collection
int index;
if ( !linkedHashSet.add(o) )
index = Arrays.asList(linkedHashSet.toArray()).indexOf(o);
again, O(n) complexity of acquiring index.
Both would incur heavy runtime penalty (the second solution is obviously worse with respect to efficiency, as it creates an array every time you seek the index; creating a parallel array mirroring the set would be better there). All in all, I see a broken abstraction in your example. You say
I need to use that index somewhere else
... if that's really the case, using Set
is 99% of the time wrong by itself.
You can, on the other hand, use a Map
(HashMap
for example), containing an [index,Object]
(or [Object,index]
, depending on the exact use case) pairs in it. It'd require a bit of refactoring, but it's IMO a preferred way to do this. It'd give you the same order of complexity for most operations as LinkedHashSet
, but you'd get O(1) for getting index essentially for free (Java's HashSet
uses HashMap
internally anyway, so you're not losing any memory by replacing HashSet
with HashMap
).
Even better way would be to use a class explicitly handling integer maps - see HashMap and int as key for more information; tl;dr - http://trove.starlight-systems.com/ has TIntObjectHashMap
& TObjectIntHashMap
, giving you possibly the best speed for such operations possible.