如何使用Object中的数据创建具有唯一对象的Set进行比较?

时间:2014-02-09 12:03:13

标签: java set unique treeset

我有“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或更多。

2 个答案:

答案 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()方法。