从 TreeSet 中删除元素时出现问题
我正在执行以下操作
class RuleObject implements Comparable{
@Override
public String toString() {
return "RuleObject [colIndex=" + colIndex + ", probability="
+ probability + ", rowIndex=" + rowIndex + ", rule=" + rule
+ "]";
}
String rule;
double probability;
int rowIndex;
int colIndex;
public RuleObject(String rule, double probability) {
this.rule = rule;
this.probability = probability;
}
@Override
public int compareTo(Object o) {
RuleObject ruleObj = (RuleObject)o;
System.out.println(ruleObj);
System.out.println("---------------");
System.out.println(this);
if(ruleObj.probability > probability)
return 1;
else if(ruleObj.probability < probability)
return -1;
else{
if(ruleObj.colIndex == this.colIndex && ruleObj.rowIndex == this.rowIndex && ruleObj.probability == this.probability && ruleObj.rule.equals(this.rule))
return 0;
}
return 1;
}
}
并且我有一个包含 RuleObject 元素的 TreeSet。 我正在尝试执行以下操作:
System.out.println(sortedHeap.size());
RuleObject ruleObj = sortedHeap.first();
sortedHeap.remove(ruleObj);
System.out.println(sortedHeap.size());
我可以看到集合的大小保持不变。我无法理解为什么它不被删除。 另外,在删除时我可以看到调用了compareTo 方法。但它只被调用了 3 个对象,而 set 中有 8 个对象。 谢谢
I am doing the following
class RuleObject implements Comparable{
@Override
public String toString() {
return "RuleObject [colIndex=" + colIndex + ", probability="
+ probability + ", rowIndex=" + rowIndex + ", rule=" + rule
+ "]";
}
String rule;
double probability;
int rowIndex;
int colIndex;
public RuleObject(String rule, double probability) {
this.rule = rule;
this.probability = probability;
}
@Override
public int compareTo(Object o) {
RuleObject ruleObj = (RuleObject)o;
System.out.println(ruleObj);
System.out.println("---------------");
System.out.println(this);
if(ruleObj.probability > probability)
return 1;
else if(ruleObj.probability < probability)
return -1;
else{
if(ruleObj.colIndex == this.colIndex && ruleObj.rowIndex == this.rowIndex && ruleObj.probability == this.probability && ruleObj.rule.equals(this.rule))
return 0;
}
return 1;
}
}
And I have a TreeSet containing elements of RuleObject.
I am trying to do the following :
System.out.println(sortedHeap.size());
RuleObject ruleObj = sortedHeap.first();
sortedHeap.remove(ruleObj);
System.out.println(sortedHeap.size());
I can see that the size of set remains same. I am not able to understand why is it not being deleted.
Also while deleting I could see compareTo method is called. But it is called for only 3 object whereas in set there are 8 objects.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
查看
删除
:您的问题是
RuleObject
不@Override equals(Object other)
。您需要这样做,当然,您还需要@Override hashCode()
。此外,
compareTo
被调用的次数少于元素数量的原因是因为它应该是一个O(log N)
操作;这就是使用 TreeSet 的全部目的。如果您有 1024 个元素,则compareTo
的调用次数预计不会超过 10 次。正如弗拉德指出的那样,你的比较器坏了。具体来说,最后一个语句
return 1;
破坏了它。您应该根据其他字段扩展相等的概率情况以返回 -1、0、+1。Look at the specification for
remove
:Your problem is that
RuleObject
does not@Override equals(Object other)
. You need to do that, and of course, with that you also need to@Override hashCode()
.Also, the reason why
compareTo
is being called fewer times than the number of elements is because it's supposed to be aO(log N)
operation; that's the whole purpose of usingTreeSet
. If you have 1024 elements, you can expectcompareTo
to be called no more than 10 times.As Vlad points out, your comparator is broken. Specifically, the last statement
return 1;
breaks it. You should expand the equalprobability
case to return -1, 0, +1 depending on the other fields.正如
polygenelubricants
所指出的,您必须在RuleObject
上实现equals
。此外,您的 比较器 本质上是破碎的。它不会强加 总排序,即在某些情况下,它会声明
RuleObject
a
既大于又小于另一个RuleObject
b
(例如,如果a.probability
= =b.probability
和a.colIndex
!=b.colIndex
。)这将导致在树插入、遍历等过程中出现不需要的行为。最后,
compareTo
还必须与equals
一致,即如果您不关心
RuleObject
的顺序,请使用HashSet
。否则(即您想要以明确定义的方式迭代 TreeSet,例如优先级、顺序),请实现 Comparable 以考虑所有感兴趣的字段,例如:
As
polygenelubricants
indicated, you must implementequals
on yourRuleObject
s.Moreover, your comparator is essentially broken. It does not impose total ordering, i.e. in certain cases it will claim that a
RuleObject
a
is both greater than and less than anotherRuleObject
b
(e.g. ifa.probability
==b.probability
anda.colIndex
!=b.colIndex
.) This will result in unwanted behaviour during tree insertion, traversal etc.In the end,
compareTo
must also be consistent withequals
, i.e.If you do not care about
RuleObject
s ordering, use aHashSet
.Otherwise (i.e. you want to iterate over the
TreeSet
in a well defined, e.g. priority, order), implementComparable
to take into account all fields of interest, e.g.:如果您希望它正常工作™,请尝试 Apache 的 CompareToBuilder,HashCodeBuilder 和 EqualsBuilder。我提供了示例代码,可以从下面开始。您当然不必采取这条路线,但我认为您会发现它简化了事情。请注意不同函数之间的一致模式。
If you want it to Just Work™, try Apache's CompareToBuilder, HashCodeBuilder, and EqualsBuilder. I have provided sample code to start from below. You certainly don't have to take this route, but I think you will find it simplifies things. Note the consistent pattern between the different functions.