hashCode概念java
hashCode是jdk根据对象的地址算出来的一个int数字,即对象的哈希码值,表明了该对象在内存中的存储位置。数组
咱们都知道hashCode()方法是顶级类Object类的提供的一个方法,全部的类均可以进行对hashCode方法重写。数据结构
咱们也知道在比较一个类是否相同时每每会重写equals方法,值得注意的是,重写equals方法的同时必须也要重写hashCode方法,屡次调用一个对象的hashCode方法必须返回同一个数字,这也是必须遵照的规范,否则会造必须存在的危害。ide
hash冲突性能
当两个对象equals相同,hashCode规定也必须相同,但反过来就不必定,两个对象对应一个hashCode,但equals却并不相等。。这就是传说中的hash冲突。HashMap是以hashCode取模数组形式存放值的,那两个对象hashCode同样会不会形成前一个对象的值覆盖呢?答案是不会,由于它采用了另一种链表数据结构来解决hash冲突的状况,即便两个对象的hashCode同样,它们会放到当前数组索引位置的链表中。spa
hashCode设计设计
HashSet经过HashMap来实现的,用来存储不重复数据的,怎么判断里面的对象是否重复呢?判断对象是否重复便是判断对象里面的属性是否都同样,这时必须是重写了equals方法去比较对象的里面全部的值,而不是比较引用地址,比较引用地址它们永远都不相等,除非是同一个对象。经过equals比较的过程性能是很是不佳的,因此有了hashCode这个设计,简单两个数字的比较性equals无法比的,因此能够先经过比较对象的hashCode是否同样肯定是否是同一个对象,若是hashCode不同这时确定就不是同一个对象,反之若是hashCode同样并且equals或者==也同样这确定就是同一个对象。因此先比较数字的hashCode再比较equals或者==,这样效率会明显提高。code
假如咱们重写了equals而不重写hashCode方法,多个对象属性值同样的它们的hashCode确定是不同的,这时做为key在put到map中的时候,就会有多个这样的key,而达不到对象做为key的场景,一样也达不到HashSet去重的效果对象
identityHashCode是System里面提供的本地方法,java.lang.System#identityHashCode。索引
/** * Returns the same hash code for the given object as * would be returned by the default method hashCode(), * whether or not the given object's class overrides * hashCode(). * The hash code for the null reference is zero. * * @param x object for which the hashCode is to be calculated * @return the hashCode * @since JDK1.1 */ public static native int identityHashCode(Object x);
identityHashCode和hashCode的区别是,identityHashCode会返回对象的hashCode,而无论对象是否重写了hashCode方法。
public static void main(String[] args) { String str1 = new String("abc"); String str2 = new String("abc"); System.out.println("str1 hashCode: " + str1.hashCode()); System.out.println("str2 hashCode: " + str2.hashCode()); System.out.println("str1 identityHashCode: " + System.identityHashCode(str1)); System.out.println("str2 identityHashCode: " + System.identityHashCode(str2)); User user = new User("test", 1); System.out.println("user hashCode: " + user.hashCode()); System.out.println("user identityHashCode: " + System.identityHashCode(user)); }
输出结果:
str1 hashCode: 96354 str2 hashCode: 96354 str1 identityHashCode: 1173230247 str2 identityHashCode: 856419764 user hashCode: 621009875 user identityHashCode: 621009875
结果分析:
一、str1和str2的hashCode是相同的,是由于String类重写了hashCode方法,它根据String的值来肯定hashCode的值,因此只要值同样,hashCode就会同样。
二、str1和str2的identityHashCode不同,虽然String重写了hashCode方法,identityHashCode永远返回根据对象物理内存地址产生的hash值,因此每一个String对象的物理地址不同,identityHashCode也会不同。
三、User对象没重写hashCode方法,因此hashCode和identityHashCode返回的值同样