基于可变属性的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()
方法,或者我的做法是错误的?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果在更改元素名称时有指向 TreeSet 的链接,只需从集合中删除该元素,更改其名称,然后重新插入即可。
如果您在更新名称时没有该链接,那么我建议将其作为 MyEntity 中的私有字段,并将 setName() 重写为
但是,这种方法非常丑陋。你最好避免它。
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
But, this approach is very ugly. You'd better avoid it.
+1 找出您的搜索不起作用的原因。在键控集合中允许键可变几乎总是错误的。
没有
set.relayout
方法。即使有,您也需要在客户端代码
上执行正确的操作,而这很容易出错。因此,您需要删除该元素并将其添加回来,这也同样容易出错。一种替代方法是使
MyEntity
可观察并扩展 TreeSet
,以便它通过删除和添加元素来响应更改的通知。不过,可能仍然存在并发问题,解决该问题的一种方法是
MyEntity
使用beforeChange
和afterChange
通知容器+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 theclient 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 andextend 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 withbeforeChange
andafterChange