【发布时间】:2014-10-18 06:45:04
【问题描述】:
所以这将是我的问题,但实际上我在写它的时候就发现了问题。也许这对其他人有用(如果问题重复或被认为不适合本网站,我将删除该问题)。我知道我的问题有两种可能的解决方案,但也许有人会想出一个比我想象的更好的解决方案。
我不明白为什么TreeSet 没有在这里删除第一个元素。我的TreeSet 的大小应该保持有界,但似乎会无限增长。
这是我认为相关的代码:
此代码位于双 for 循环内。 NUM_GROUPs 是一个 static final int,它被设置为 100。 newGroups 是一个 TreeSet<TeamGroup> 对象,在双 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 调用没有删除任何内容 - 但它如何不从对 first() 的调用中删除一些内容? 肯定是TreeSet中的一个元素?
这是我的TeamGroup 类中的compareTo 方法(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;
}
这是我的TeamGroup 类的equals 方法:
@Override
public boolean equals(final Object o) {
return this.R_ID == ((TeamGroup) o).R_ID;
}
...我不担心这里的ClassCastException,因为这与我的上述问题特别相关,我从不尝试将TeamGroup 对象与另一个TeamGroup 对象进行比较——这是绝对不是问题(至少不是ClassCastException问题)。
R_ID 应该是唯一的,我通过以下方式保证这一点:
private static final double WIDTH = (double) Integer.MAX_VALUE
- (double) Integer.MIN_VALUE;
private static final Map<Integer, Integer> MAPPED_IDS =
new HashMap<Integer, Integer>(50000);
...
public final int R_ID = TeamGroup.getNewID();
...
private static int getNewID() {
int randID = randID();
while (MAPPED_IDS.get(randID) != null) {
randID = randID();
}
MAPPED_IDS.put(randID, randID);
return randID;
}
private static int randID() {
return (int) (Integer.MIN_VALUE + Math.random() * WIDTH);
}
【问题讨论】:
-
这是实施
compareTo的一个众所周知的问题......但我找不到合适的问答作为最终副本。 (如果其他人可以,请这样做。) -
@StephenC 你提到的众所周知的问题是什么?就像我说的,我知道问题出在哪里,它是在
compareTo方法中,但它与compareTo方法本身没有任何关系。真正的问题在于bothcompareTo方法和我正在使用排序集这一事实。 -
没有。问题是您的
compareTo实施不正确。众所周知,那样实现它是不正确的。 -
@StephenC 好吧,我显然不同意你的观点(
compareTo方法 is 绝对错误地实现了),但是为什么这会导致我遇到的问题(我意识到你的回答触及了原因)。
标签: java twos-complement