This is a difficult question I came up against the other day myself. java.util.LinkedHashSet
maintains a linked list of its contents (addition-ordered by default) but does not provide any accessors. Other structure types will fail to provide O(1) on add()
, remove()
, and contains()
.
You can use a LinkedHashSet
and get its iterator()
, grab one element, and discard it. If you don't care too much about speed or memory when doing this frequently to numerous different sets, that is probably your solution... but that seemed wasteful to me. Plus I had a little extra desired functionality.
I ended up writing my own class, dubbed RandomAccessLinkedHashSet
, which concurrently maintains a hashtable, a doubly linked list, and an order-irrelevant array. I wrote it to comply with both Set
and Deque
, though the Deque implementation is a little sketchy since it will fail to push()
elements it already contains, a little bit of a stretch for the interface's contract. Maintaining the third structure, the array, is not necessary at all for what you're doing, but it also allows access to a random element in the set in whatever capacity you can actually provide a random value.
If you're interested I can provide this source. I haven't Serialized
it yet but it works great in runtime.
If you cannot guarantee the type of Set
provided in any way, then you'll have to stick with the Iterator
thing.