我有“Var”的TreeSet Var 是我自己的类: http://pastebin.com/pXC4q2YB
我需要“字符串”对于 Var 的 TreeSet 来说是唯一的 因此集合中的任何 Var 都不能具有相同的“string”/“.getKey()”
<小时/>我重写了compareTo方法,但是当我向该集合添加值时...
这仍然使用相同的键添加 Var...
<小时/>我添加了一些调试...并且compareTo 对于某些组合不运行。
一开始,我有 8 个变量,接下来我会继续添加,但每次 Var.replace 中的一些元素都是不同的,所以在第二次添加之后,我有 14 个元素……再添加一些……30 个元素,最后,在集合中获得 30 Var 后,接下来将停止添加。
<小时/>PS:我使用该代码添加: http://pastebin.com/N372QUck
“变量”是 Var 的集合
我经常使用此代码,因此速度不会很慢,8 个变量仅用于测试,如果有人愿意,可以增加约 50 个或更多。
最佳答案
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) 必须抛出异常。)
上面的代码将允许多个 null 值,因为它返回 1 而不是抛出 NPE
2)TreeSet是自平衡树。这意味着您认为对象相等的东西可能不会被treeSet用于比较,因为它不断添加对象。Treeset将按照Comparable定义的特定顺序遍历树或 Comparator 并根据compareTo(-1,0,1)返回的值不断在节点之间遍历。因此,很有可能在添加元素时甚至没有遇到你的“相等”对象进行比较。注意,TreeSet不是普通的List、Array之类的顺序遍历,而是树的遍历。
要解决这些问题,您需要确保您的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()) ;
}
这应该可以解决您的所有问题
关于java - 如何使用对象中的数据创建具有唯一对象的集合进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21658804/