所以这就是我的问题,但实际上我在写这个问题时已经找到了问题。也许这对其他人有用(我会删除这个问题,如果它是重复的或被认为不适合这个网站)。我知道我的问题有两个可能的解决方案,但也许有人会想出一个比我想象的更好的解决方案。
我不明白为什么TreeSet
没有删除第一个元素。我的TreeSet
的大小应该保持有限,但似乎无限制地增长。
以下是我认为的相关代码:
此代码驻留在double for循环内。 NUM_GROUPs
是static final int
,设置为100
。 newGroups
是一个TreeSet<TeamGroup>
对象,它在double for循环之前被初始化(没有元素)(变量group
和team
来自两个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
答案 0 :(得分:2)
问题在于:
return this.R_ID - o.R_ID;
应该是:
return Integer.compare(this.R_ID, o.R_ID);
如果值保证为非负值,则取两个int
或Integer
值的差异。但是,在您的示例中,您在int
/ Integer
的整个范围内使用ID值,这意味着减法可能会导致溢出... compareTo
的结果不正确
不正确的实现导致compareTo
方法没有反身的情况;即整数I1
,I2
和I3
,其中compareTo
方法表示I1 < I2
和I2 < I3
,还有I3 < I1
。当您将其插入TreeSet
时,元素会在错误的位置插入树中,并发生奇怪的行为。确切地说,正在发生的事情很难预测 - 它将取决于插入的对象以及插入的顺序。
TreeSet.first()
肯定会返回一个属于该集合的对象,对吗?
可能......
那么为什么它不能删除这个对象呢?
可能是因为找不到它......因为比较破坏了。
要了解究竟发生了什么,您可以单步执行TreeSet代码,等等。