2

我的问题是非常基本的,但我不知道如何正确解决它。我有一个 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()我应该调用的方法,还是我做错了?

4

2 回答 2

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);
  }
}

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

于 2012-01-25T18:14:53.073 回答
2

+1 用于找出您的搜索不起作用的原因。允许键在键控集合中可变几乎总是错误的。

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

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

但是可能仍然存在并发问题,解决它的一种方法是MyEntity通知容器beforeChangeafterChange

于 2012-01-25T18:16:31.890 回答