Java 基于可变属性的树集比较器

Java 基于可变属性的树集比较器,java,data-structures,treeset,Java,Data Structures,Treeset,我的问题很基本,但我不知道如何正确地解决它。我有一个树集,它使用基于实体名称的比较器。但是,我可以改变这个名字。如何强制重新排序树集 TreeSet<MyEntity> set = new TreeSet<MyEntity>(new BeanComparator("name")); // bar < foo < xander set.add(foo); set.add(bar); set.add(xander); // resulting tree:

我的问题很基本,但我不知道如何正确地解决它。我有一个树集,它使用基于实体名称的比较器。但是,我可以改变这个名字。如何强制重新排序树集

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'
TreeSet set=newtreeset(newbeancomparator(“name”);
//bar错,因为现在“foo”或“bar”都不等于“xander”

是否有一些我应该调用的
set.relayat()
方法,或者我的做法完全错了?

如果在更改元素名称时有指向树集的链接,只需从集合中删除该元素,更改其名称,然后重新插入即可

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

公共类MyEntity{
专用最终树集容器;
...
public void setName(最终字符串名){
容器。移除(此);
this.name=名称;
容器。添加(此);
}
}

但是,这种方法非常丑陋。您最好避免使用它。

如果在更改元素名称时有指向树集的链接,只需从集合中删除该元素,更改其名称,然后重新插入即可

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

公共类MyEntity{
专用最终树集容器;
...
public void setName(最终字符串名){
容器。移除(此);
this.name=名称;
容器。添加(此);
}
}

但是,这种方法非常丑陋。您最好避免使用它。

+1查找您的搜索不起作用的原因。允许密钥在已设置密钥的集合中可变几乎总是错误的

没有设置
。请重新设置
方法。即使有,您也需要在
客户机代码上执行正确的操作,这很容易出错

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


尽管如此,仍然可能存在并发问题,解决此问题的一种方法是,
MyEntity
在更改前用
通知容器,并在更改后用
通知容器,以找出搜索不起作用的原因。允许密钥在已设置密钥的集合中可变几乎总是错误的

没有设置
。请重新设置
方法。即使有,您也需要在
客户机代码上执行正确的操作,这很容易出错

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

尽管如此,仍然可能存在并发问题,解决此问题的一种方法是,
MyEntity
在更改前和更改后通知容器

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

  ...

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