我有“Var”的TreeSet Var是我自己的类: http://pastebin.com/pXC4q2YB
我需要“string”对于Var的TreeSet是唯一的 所以任何来自集合的Var都不能有相同的“string”/“。getKey()”
我重写compareTo方法,但是当我向该组添加值时......
这仍然使用相同的密钥添加Var ...
我添加了一些调试...并且compareTo不会运行某些组合。
首先我有8个变量,然后我继续添加,但每次Var.replace的一些不同,所以在第二次添加后我有14个元素......经过一些更多...... 30,那个结束,在获得30 Var之后,它会停止添加下一个。
PS:我使用该代码添加: http://pastebin.com/N372QUck
“变量”是Set of Var
我经常使用这个代码,因此不能很慢,8个变量仅用于测试,如果有人需要,可以大约50或更多。
答案 0 :(得分:1)
TreeSet中的关键是自然排序不仅用于对象比较,还用于遍历树。
你的compareTo方法确实存在一个很大的缺陷,用于实现自然排序。让我粘贴代码,然后指出它的缺陷: -
@Override
public int compareTo(Var var) {
if (var == null)
return 1;
return var.getKey().equals(this.getKey()) ? 0 : 1;
}
我们的Comparable的compareTo方法中的违规行为: -
1)实现者必须确保所有x和y的sgn(x.compareTo(y))== -sgn(y.compareTo(x))。 (这意味着如果y.compareTo(x)抛出异常,x.compareTo(y)必须抛出异常。)
上面的代码将允许多个空值,因为它返回1而不是抛出NPE
2)TreeSet是自平衡树。这意味着你认为对象为equals的东西可能不被treeSet用于比较,因为它继续添加对象.Treeset将按照Comparable定义的特定顺序遍历树。或比较器,并根据compareTo(-1,0,1)返回的值继续遍历节点.Hence,很有可能在添加元素时甚至不会遇到“相等”对象进行比较。注意,TreeSet不是普通的顺序遍历,如List或数组,而是树遍历。
要解决这些问题,您需要确保compareTo(Var var)方法遵循Object的equals协定
更好的代码是: -
@Override
public int compareTo(Var var) {
if (var == null)
throw new NullPointerException("Object is null");
return this.getKey().compareTo(var.getKey()) ;
}
这应解决您的所有问题
答案 1 :(得分:0)
compareTo用于评估更大/更小/相等。
集合方面的平等是通过覆盖Object#equals(Object)方法确定的。 每当实现equals()时,您还应该实现hashCode()方法。