关于TreeSet的调试挑战

时间:2014-10-18 06:45:05

标签: java twos-complement

所以这就是我的问题,但实际上我在写这个问题时已经找到了问题。也许这对其他人有用(我会删除这个问题,如果它是重复的或被认为不适合这个网站)。我知道我的问题有两个可能的解决方案,但也许有人会想出一个比我想象的更好的解决方案。

我不明白为什么TreeSet没有删除第一个元素。我的TreeSet的大小应该保持有限,但似乎无限制地增长。

以下是我认为的相关代码:

此代码驻留在double for循环内。 NUM_GROUPsstatic final int,设置为100newGroups是一个TreeSet<TeamGroup>对象,它在double for循环之前被初始化(没有元素)(变量groupteam来自两个for-each循环)。

final TeamGroup newGroup = new TeamGroup(group, team);
newGroups.add(newGroup);
System.err.println("size of newGroups: " + newGroups.size());
if (newGroups.size() > NUM_GROUPS) {
    System.err.println("removing first from newGroups");
    newGroups.remove(newGroups.first());
    System.err.println("new size of newGroups: "
        + newGroups.size());
}

我包含了我的调试语句,以表明问题确实发生了。我得到以下类型的输出:

size of newGroups: 44011
removing first from newGroups
new size of newGroups: 44011

您会看到虽然明确输入了if语句,但TreeSet<TeamGroup> teamGroups的大小并未减少。在我看来,发生这种情况的唯一方法是remove调用不会删除任何内容 - 但是如何从调用{{1}中删除某些内容肯定应该是first()

中的一个元素

以下是我的TreeSet课程中的compareTo方法TeamGroup是一个score,对于许多不同的int对象来说,这可能非常合理为什么我使用TeamGroup字段作为打破平局者:

R_ID

以下是public int compareTo(TeamGroup o) { // sorts low to high so that when you pop off of the TreeSet object, the // lowest value gets popped off (and keeps the highest values). if (o.score == this.score) return this.R_ID - o.R_ID; return this.score - o.score; } 课程的equals方法:

TeamGroup

...我并不担心这里的@Override public boolean equals(final Object o) { return this.R_ID == ((TeamGroup) o).R_ID; } ,因为这与我上面的问题有关,我从不尝试将ClassCastException对象与另一个TeamGroup对象进行比较对象 - 这肯定是问题(至少不是TeamGroup问题)。

ClassCastException应该是唯一的,我通过以下方式保证:

R_ID

1 个答案:

答案 0 :(得分:2)

问题在于:

        return this.R_ID - o.R_ID;

应该是:

        return Integer.compare(this.R_ID, o.R_ID);

如果值保证为非负值,则取两个intInteger值的差异。但是,在您的示例中,您在int / Integer的整个范围内使用ID值,这意味着减法可能会导致溢出... compareTo的结果不正确

不正确的实现导致compareTo方法没有反身的情况;即整数I1I2I3,其中compareTo方法表示I1 < I2I2 < I3,还有I3 < I1。当您将其插入TreeSet时,元素会在错误的位置插入树中,并发生奇怪的行为。确切地说,正在发生的事情很难预测 - 它将取决于插入的对象以及插入的顺序

  

TreeSet.first()肯定会返回一个属于该集合的对象,对吗?

可能......

  

那么为什么它不能删除这个对象呢?

可能是因为找不到它......因为比较破坏了。

要了解究竟发生了什么,您可以单步执行TreeSet代码,等等。