Search code examples
javadata-structurestreeset

TreeSet comparator based on mutable attribute


My problem is very basic, but I have no clue how to solve it correctly. I have a TreeSet which uses a comparator based on the name of the entity. However, I can change that name. How do I force a reordering of the TreeSet?

TreeSet<MyEntity> set = new TreeSet<MyEntity>(new BeanComparator("name"));
// bar < foo < xander
set.add(foo);
set.add(bar);
set.add(xander);
// resulting tree:     _-foo-_
//                   bar    xander
xander.setName("apple");

set.contains(xander); // -> false, since now neither 'foo' or 'bar' are equal to 'xander'

Is there some set.relayout() method I should be calling, or am I going about this all wrong?


Solution

  • If you have a link to the TreeSet when you changing the name of elements, just remove that element from the set, change its name, and insert back.

    If you don't have that link at the time of updating name, then I'd suggest to have it as a private field in MyEntity, and rewrite setName() as

    public class MyEntity {
      private final TreeSet<MyEntity> container;
    
      ...
    
      public void setName(final String name) {
        container.remove(this);
        this.name = name;
        container.add(this);
      }
    }
    

    But, this approach is very ugly. You'd better avoid it.