【问题标题】:TreeSet comparator based on mutable attribute基于可变属性的 TreeSet 比较器
【发布时间】:2012-01-25 18:06:39
【问题描述】:

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

【问题讨论】:

    标签: java data-structures treeset


    【解决方案1】:

    如果在更改元素名称时有指向 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);
      }
    }
    

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多