万丈高楼平地起,今天的聊点基础而又常常让人忽视的话题,好比“==”与“equals()”区别?为什么当咱们重写完"equals()"后也要有必要去重写"hashcode()"呢? ... 带着这些问题,咱们一块儿来探究一下。java
"==":它主要是判断符号两边的“对象”的值是否相等,而这里的“值“”又有所区分了。面试
基础数据类型:比较的就是自身的值,这个跟咱们常规的理解是基本一致的。算法
引用数据类型:比较的对象的内存地址。数组
“equals()”:它也是用来判断两个对象是否相等,因此也得分不一样的状况来讲明。微信
在当前类中,没有重写equals方法的话,默认的实现跟"=="的实现是同样的。下面是Object类的equals方法实现。ide
在当前类中,重写了equals方法,此时判断的依据就是你重写的逻辑。函数
由此能够看出,重写一个equals()方法,须要注意的点仍是比较多的,这里给出一个参考的事例。this
public class EqualsDemo { private String name; private String info; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; EqualsDemo that = (EqualsDemo) o; if (name != null ? !name.equals(that.name) : that.name != null) return false; return info != null ? info.equals(that.info) : that.info == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (info != null ? info.hashCode() : 0); return result; } }
有些读者可能会感到奇怪,不是说重写equals()方法吗,为何这里又出现了一个hashcode()?因此这里又引出了咱们的另外一个主角hashcode()方法,当咱们重写了equals()方法后,它就必定会出现,也会“吵着“本身也要被重写。spa
hashCode() 的做用是获取哈希码,也称为散列码;它返回的一个int整数。这个哈希码的做用是肯定该对象在哈希表中的索引位置。hashCode方法的主要做用是为了配合基于散列的集合一块儿正常运行,这样的散列集合包括HashSet、HashMap、HashTable等。它定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。.net
当咱们在上面的集合插入对象的时候,java是怎么知道里面是否有重复的对象呢?可能你们第一反应是equals方法,没错这方法能够实现这个功能,可是当集合里面有成千上万个元素的时候,效率会如何呢?答案固然是比较差了,因此才会出现了哈希码。
public V put(K key, V value) { //判断当前数组是否等于{},如果则初始化数组 if (table == EMPTY_TABLE) { inflateTable(threshold); } //判断 key 是否等于 null,是则将把当前键值对添加进table[0]中,遍历table[0]链表 //若是已经有null为key的Entry,则修改值,返回旧值,若无则直接添加。 if (key == null) return putForNullKey(value); //key不为null则计算hash int hash = hash(key); //搜索对应hash所在的table中的索引 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; }
这里是jdk7中 Hashmap put()方法的实现,经过源码的注释能够看出执行的流程,须要更详细的了解HashMap能够参考我以前发在开源中国的博客《Java7 HashMap全面解读! 》,连接:https://my.oschina.net/199212...
通过概念的介绍,知道为何重写完equals()后要接着重写hashcode()了吧?
People p1=new People("小明",18); People p2=new People("小明",18);
此时重写了equals方法,p1.equals(p2)必定返回true,假如只重写equals而不重写hashcode,那么Student类的hashcode方法就是Object默认的hashcode方法,因为默认的hashcode方法是根据对象的内存地址经哈希算法得来的,显然此时s1!=s2,故二者的hashcode不必定相等。因此在一些集合的使用当中会出现问题。
小小的几个方法,没想到却有这么多“坑”,并且在面试中也会常常被问到,在金三银四的时候,希望各位不会陷在这里。
喜欢的话,关注一下微信公众号《深夜里的程序猿》,天天更新高质量IT文章