基于mutable属性的TreeSet比较器

时间:2012-01-25 18:06:40

标签: java data-structures treeset

我的问题非常基础,但我不知道如何正确解决问题。我有一个TreeSet,它使用基于实体名称的比较器。但是,我可以更改该名称。如何强制重新排序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'

我应该调用一些set.relayout()方法,还是我说错了?

2 个答案:

答案 0 :(得分:2)

如果在更改元素名称时有TreeSet链接,只需从集合中删除该元素,更改其名称并插回。

如果您在更新名称时没有该链接,那么我建议将其作为MyEntity中的私有字段,并将setName()重写为

public class MyEntity {
  private final TreeSet<MyEntity> container;

  ...

  public void setName(final String name) {
    container.remove(this);
    this.name = name;
    container.add(this);
  }
}

但是,这种做法非常难看。你最好避免它。

答案 1 :(得分:2)

+1,用于查找搜索无效的原因。允许密钥在密钥集合中是可变的几乎总是错误的。

没有set.relayout方法。即使有,你也需要在client code做正确的事情,这很容易出错。

所以你需要删除元素并将其重新添加,这也同样容易出错。另一种方法是使MyEntity可观察和extend TreeSet,以便通过删除和添加元素来通知它响应的更改。

可能仍然存在并发问题,解决问题的一种方法是MyEntity通过beforeChangeafterChange

通知容器