我的代码有两组,在它们上添加了相同的元素集合。问题是,TreeSet不会添加所有元素。我有点困惑。

我现在有一个问题,我一直在努力找出为什么我的TreeSet不会添加我传递给addAll的集合中的所有元素的原因。

这是一个带有比较器的TreeSet构建,用于具有equals方法的项目,例如:

public final boolean equals(Object o) {
    return this==o;
}

@Override
public int hashCode() {
    int hash = 3;
    hash = 67 * hash +     Objects.hashCode(this.grauDeAdaptacao);
    hash = 67 * hash + Objects.hashCode(this.idade);
    return hash;
}


为了测试,我做了以下工作:

HashSet<Item> test1 = new HashSet<>(items);
TreeSet<Item> test2 = new TreeSet<>(getComparator());
test2.addAll(items);
if (test1.size() < 50 || test2.size()<50 ) {
    throw new IllegalStateException();
}


比较器使用:

private int compare(S ser1, S ser2) {
    return ser1.getGrau().compareTo(ser2.getGrau());
}


但是尴尬的是,哈希接缝很好,而TreeSet没有全部50个元素。

在所有子类中,当两个元素都是相同的实例时,我需要两个元素相等,这就是为什么我要像这样最终的方法。

最佳答案

HashSet使用equals测试两个对象是否相等。

HashSet保证对于a b中的任何两个不同的对象Seta.equals(b) == true绝对不会发生这种情况。

TreeSet使用compareTo测试两个对象是否相等。

TreeSet保证对于a b中的任何两个不同的对象Seta.compareTo(b) == 0绝对不会发生这种情况。

a.compareTo(b) == 0 iff a.equals(b)的假设下,此行为是相同的。在这种情况下,可以说compareTo方法与documentation for equals中定义的“与Comparable一致”。

同一文档还指出:


  强烈建议(尽管不是必需的)自然
  顺序与等式一致。这是因为排序集
  没有显式比较器的(和排序映射)在以下情况下的行为“奇怪”
  它们与自然顺序为的元素(或键)一起使用
  与平等不一致。特别是这样的排序集(或已排序
  map)违反了定义的set(或map)的一般合同
  就等于方法而言。


这是“奇怪地表现”的一个例子。

您有一些a.equals(b) == falsea.compareTo(b) == 0的对象。

还应注意,对于hashCode的实现,要求a.equals(b) == truea.hashCode() == b.hashCode()。在您的实现中情况并非如此。给定hashCode()的实现,您对equals的实现无效。

不需要反射性。即a.hashCode() == b.hashCode()a.equals(b) == false可能(并且将会是)。

因此,总而言之。


您的hashCodeequals错误。它们需要保持一致,如equalshashCode的文档中所述。
您的comapreTo是错误的,它应该与documentation for equals中所述的“与Comparable一致”。

关于java - TreeSet没有添加所有元素和HashSet,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24656874/

10-15 16:26