Search code examples
javasetguava

Removing the "first" object from a Set


Under certain situations, I need to evict the oldest element in a Java Set. The set is implemented using a LinkedHashSet, which makes this simple: just get rid of the first element returned by the set's iterator:

Set<Foo> mySet = new LinkedHashSet<Foo>();
// do stuff...
if (mySet.size() >= MAX_SET_SIZE)
{
    Iterator<Foo> iter = mySet.iterator();
    iter.next();
    iter.remove();
}

This is ugly: 3 lines to do something I could do with 1 line if I was using a SortedSet (for other reasons, a SortedSet is not an option here):

if (/*stuff*/)
{
    mySet.remove(mySet.first());
}

So is there a cleaner way of doing this, without:

  • changing the Set implementation, or
  • writing a static utility method?

Any solutions leveraging Guava are fine.


I am fully aware that sets do not have inherent ordering. I'm asking about removing the first entry as defined by iteration order.


Solution

  • LinkedHashSet is a wrapper for LinkedHashMap which supports a simple "remove oldest" policy. To use it as a Set you can do

    Set<String> set = Collections.newSetFromMap(new LinkedHashMap<String, Boolean>(){
        protected boolean removeEldestEntry(Map.Entry<String, Boolean> eldest) {
            return size() > MAX_ENTRIES;
        }
    });