Java 为什么';在添加新元素之前是否比较所有元素?

Java 为什么';在添加新元素之前是否比较所有元素?,java,equals,hashset,treeset,Java,Equals,Hashset,Treeset,我试着编写一个程序来存储由两个字符串组成的非相等对对象。就这点而言,这对(约翰,鲍勃)被认为与(鲍勃,约翰)相等。我的equals和compareTo实现应该可以正常工作。为了检查有什么问题,我让我的程序输出我尝试添加的每一对的比较结果。看起来像这样: @Override public boolean equals(Object o){ if (o==null){ return false; } final Pair other = (Pair) o;

我试着编写一个程序来存储由两个字符串组成的非相等对对象。就这点而言,这对(约翰,鲍勃)被认为与(鲍勃,约翰)相等。我的equals和compareTo实现应该可以正常工作。为了检查有什么问题,我让我的程序输出我尝试添加的每一对的比较结果。看起来像这样:

@Override
public boolean equals(Object o){
    if (o==null){
        return false;
    }
    final Pair other = (Pair) o;
    return (this.compareTo(other)==0);
}



@Override
public int compareTo (Pair o){
  if (this.first.equals(o.first)){
      if (this.second.equals(o.second)){
          System.out.println("equal: "+this.first+" "+this.second+" and  " + o.first+" "+o.second);
          return 0;
      }
  }
  else if (this.first.equals(o.second)){
        if (this.second.equals(o.first)){
            System.out.println("equal: "+this.first+" "+this.second+" and  " + o.first+" "+o.second);
            return 0;
        }
  }
    System.out.println(" not equal " +this.first+" "+this.second+" and  " + o.first+" "+o.second);
  return -1;
示例输入:

 bob john
 john john
 john john
 john bob
 bob will
 john hohn
如果我让它运行,它会在每次尝试后打印出树的大小,以添加一个新元素。它还将打印compareTo方法中写入的内容。我添加了注释来说明我的问题

   equal: bob john and  bob john    //Why comparing the first element at  
                                      all?
1
 not equal john john and  bob john
2
 not equal john john and  bob john
equal: john john and  john john
2
equal: john bob and  bob john
2
 not equal bob will and  bob john
 not equal bob will and  john john
3

 not equal john hohn and  john john    //no comparision of (john hohn) and                                       
 not equal john hohn and  bob will     //(bob john) why?
4
一: 回答您的问题:TreeSet不需要比较所有元素,因为元素有一个已定义的顺序。考虑一本字典:在中间打开它,你会立刻知道,如果你需要的单词是在页面之前或之后。你不需要检查字典的两部分

二: 您的compareTo()方法有错误。考虑两个对象:

Pair a = Pair.of(1, 2);
Pair b = Pair.of(3, 4);
您的compareTo()在这两种情况下都将返回-1,但它不能:

a.compareTo(b) == -1
b.compareTo(a) == -1
从数学上讲,您的关系“compareTo”没有定义订单,因此违反了合同:

实现者必须确保所有x和y的sgn(x.compareTo(y))==-sgn(y.compareTo(x))


这就是基于树的结构的优点——实际上,您不必访问每个元素来执行某些操作。因此,您可以获得次线性(具体地说,对数)复杂性。在
比较中,您永远不会返回
1
,这意味着传递给它的对象是相等或更小的,但永远不会返回bigger@Eugene如果您要插入BST,您肯定不需要比较集合的所有元素来找到集合的正确位置,是吗?TreeSet已排序,您无法关闭它。您为它提供了一个无法正常进行排序的compareTo,因此引用API文档“它只是未能遵守Set接口的一般约定”。HashSet通常不会对所有内容进行比较,如果您有一个好的hashCode(无冲突),它应该只进行一次比较。冲突是两个或多个共享相同哈希代码值的不相等元素,然后通过相等来区分它们。