基于可变属性的TreeSet比较器

发布于 2024-12-28 17:30:42 字数 519 浏览 2 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

动听の歌 2025-01-04 17:30:42

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

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

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.

自此以后,行同陌路 2025-01-04 17:30:42

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

没有 set.relayout 方法。即使有,您也需要在客户端代码上执行正确的操作,而这很容易出错。

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

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

+1 for finding out why your search is not working. It is almost always wrong to allow a key to be mutable in a keyed collection.

There is no set.relayout method. Even if there was, you would need on the client code to do the right thing and that is very error-prone.

So you need to remove the element and add it back in, which is also equally error-prone. One alternative is to make MyEntity observable and extend TreeSet so that it gets notified of changes which it responds to by removing and adding the element.

There may still be concurrency concerns though, one way to solve it is for MyEntity to notify the container with beforeChange and afterChange

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文