Java equals compareTo()的区别

Java equals compareTo()的区别

JDK源代码尤其是集合框架源代码的时候,经常会看见两个方法:

int equals(Object obj);
int compareTo(Object obj); 

在集合框架中大多数集合类是采用equals方法来对key进行区分的,例如HashMapLinkedHashMapHashSetLinkedHashSet等等;

而有些集合类是采用compareTo方法来对key进行区分的,例如TreeMapTreeSet等,这一类集合的key通常是具有顺序性的,都直接或间接的实现了
SortedMapSortedSet接口。

对于compareTo方法,它是接口Comparable接口的一个方法;除此之外,还有另一个接口Comparator,里面含有一个方法compare(T a, T b)
而对于equals方法,是属于顶级类Object类的一个方法,查看Object的源代码便可以发现:

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

对于上述提及的equalsComparablecompareTo方法、Comparatorcompare(T a, T b)方法:

方法说明
a.equals(b) 比较 对象ab是否逻辑相等(可以是==比较),但是也可以重写自定义相等的含义
a == b 操作符,比较俩引用引用的对象是否物理上是同一个对象
a.compareTo(b) 比较对象ab的自然顺序
compare(a, b) a.compareTo(b)

需要补充说明的是:

  • compareTo()方法属于接口Comparable,因此不是所有的类都拥有该方法,因为有些类根本不具有比较大小的属性;
  • compareTo()的参数不能为null;而equals()的参数可以是null,返回值false;
  • 在实现Comparable接口的compareTo方法时,强烈推荐与equals的结果一致,否则可能会出现一些奇怪的错误;因为有些类是利用equals来判断重复性,
    而有些类是利用自然顺序x.compareTo(y) == 0来判断,官方文档强烈推荐:(x.compareTo(y)==0) == (x.equals(y));

举两个例子,HashMapput方法中有如下代码:


for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {//先用==比较,然后再用equals比较
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

而在TreeMapput方法中有如下代码:


if (key == null)
                throw new NullPointerException();
            Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);//通过compareTo方法来比较
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);

文档中关于这个给了一些说明:

Virtually all Java core classes that implement Comparable have natural orderings that are consistent with equals.
One exception is java.math.BigDecimal, whose natural ordering equates BigDecimal objects with equal values and different precisions (such as 4.0 and 4.00).

java中大部分类都保持了equalscompareTo的一致性,但有一个反例就是BigDecimal

 

posted @ 2017-11-19 17:37  Spground  阅读(207)  评论(0编辑  收藏  举报