为什么TreeSet在添加新元素之前不比较所有元素?

时间:2019-04-05 09:50:16

标签: java equals hashset treeset

我尝试编写一个程序,该程序存储由2个字符串组成的不相等的成对对象。因此,该对(john,bob)被认为等于(bob,john)。我的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

如果我让它运行,它将在每次尝试后打印出TreeSat的大小以添加一个新元素。它还将打印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

1 个答案:

答案 0 :(得分:2)

一个: 要回答您的问题: 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”未定义订单,因此违反了API合同:

  

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