一、 equals与==

==

对于基本数据类型(int, float, double, short, long, boolean, char, byte),==比较的是他们的值,而对于引用类型,返回的使他们引用的比较(也就是地址的比较);

equals

equals()是Object类下的一个方法,默认其内部实现就是通过==实现的。

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

二者区别

  1. equals()只能对对象使用,如果对象为null将会空指针异常,而==既可以对基本数据类型使用也可以对引用类型使用,在对引用类型使用时,equals()等价于==;
  2. equals()大部分场景下会被重写,重写成对于值得比较,比如String重写的equals()方法;
public boolean equals(Object anObject) {
    if (this == anObject) {//参数是否为这个对象的引用
        return true;
    }
    if (anObject instanceof String) {//参数是否为正确的类型
        String anotherString = (String)anObject;
	//获取关键域,判断关键域是否匹配
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
}

二、hashCode()

引入

Java中的集合主要分为两类:ListSet,其中List表示有序集合,因为有序(这里的有序并不单指数组,包括链表,队列都可看做是有序的集合,有序是元素插入、删除有先后顺序),所以集合元素可以重复;而Set本身是无序集合(如HashMap, HashSet, HashTable),元素不允许出现重复。
那么Set如何判断一个元素是否在集合中已经存在呢,当然我们可以遍历整个集合,但这样每次添加一个元素都对整个集合进行一次遍历,效率非常低。这里我们引入hashCode()

定义

hashCode()的作用就是返回一个hash码(int),这个hash码作为对象散列的key输入,我们需要尽可能保证每个对象的hash码不同,以便对对象进行区分,实际上Java确实能保证这点,它是通过对对象的地址进行一定的运算生成对象的hash码。

作用

无序集合内部通常会对所有元素的hash码进行保存,以HashMap为例,其内部存在一个table用以保存所有元素的hash码,当需要往无序集合(如HashMap)中添加一个新的对象时,首先调用这个对象的hashCode()方法获取其hash码,如果在table中找不到此对象的hash码,则直接添加,如果能找到,则调用equals()方法比较两个对象是否相同,如果相同就不进行保存,如果不同就重新hash,散列到另一个地址。这样等于是存在一个冲突处理,大大降低了equals()调用频率,进而显著提高了往无序集合中添加元素的效率。

public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        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))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
 
        modCount++;
        addEntry(hash, key, value, i);
        return null;
 }

这是HashMap中put的实现。