Object.hashCode()方法与System.identityHashCode(object)的区别

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

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返回的值同样

相关文章
相关标签/搜索