zoukankan      html  css  js  c++  java
  • & hashCode()和equals()的作用、区别、联系

    哈希码(HashCode)

    哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看程序员如何写哈希码的算法。

    在Java中哈希码代表对象的特征。
    例如:

    String str1 = "aa";
    String str2 = "bb";
    String str3 = "aa";
    
    str1.hashCode = 3104
    str2.hashCode = 3106
    str3.hashCode = 3104

    根据hashCode由此可得出 str1!=str2 str1==str3

    下面给出几个常用的哈希码的算法:

    1. Object类的hashCode返回对象的内存地址经过处理后的结果,由于每个对象的内存地址都不一样,所以哈希码也不一样。
    2. String类的hashCode,根据String类包含的字符串的内容,根据一种特殊算法返回hashCode,只要字符串所在的堆空间相同,返回的哈希码也相同。
    3. Integer类,返回的哈希码就是Integer对象里所包含的哪个整数的数值,列如 Integer i1 = new Integer(100);,那么i1.hashCode的值就是100。因此,2哥一样大小的Integer对象,返回的哈希码也一样。

    equals()

    1. 默认情况(没有重写equals方法)下equals方法都是调用Object类的equals方法,而Object的equals方法主要判断对象的内存地址引用是不是同一个地址(是不是同一个对象)。
    2. 要是类中重写了equals方法,则就要根据重写后的equals方法进行比较,一般都是通过对象的内容是否相等来判断对象是否相等。

    equals()与hashCode()的比较

    hashCode()和equals()一样都是基本类Object里的方法,他们作用其实一样,都是用来对比两个对象是否相等一致。

    • 那么equal()既然已经能实现对比的功能了,为什么还要hashCode()呢?
      因为:重写的equals()方法中的逻辑一般比较全面比较复杂,这样效率就很低,而利用hashCode()进行比较,则只要生成一个hash值进行比较就行了,效率很高。
    • 那么hashCode()既然效率这么高为什么还要equals()?

      因为:hashCode()并不是完全可靠的,有时候不同的对象他们生成的hashcode也会一样(生成的hash值的算法公式可能存在问题),所有hashCode()只能说是大部分时候可靠,并不是绝对可靠。

    • 结论:
      • equals()相等的两个对象他们的hashCode肯定相等,也就是用equals()比较是绝对可靠的。
      • hashCode()相等的两个对象他们的equals()不一定相等,也就是hashCode()不是绝对可靠的。
      • 因此对于需要大量并且快速的对比的话如果都用equals()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equals()去再对比了),如果hashCode()相同,此时再对比他们的equals(),如果equals()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!
      • 一般重写了equals(),就要重写hashCode()。

    hashCode()在集合中用的多

    HashSet,HashMap,HashTable等等,这种大量的并且快速的对象对比一般使用的hash容器中,比如hashSet里要求对象不能重复,则他内部必然要对添加进去的每个对象进行对比,而他的对比规则就是像上面说的那样,先hashCode(),如果hashCode()相同,再用equal()验证,如果hashCode()都不同,则肯定不同,这样对比的效率就很高了。

    将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。
    如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。

    img

    map.put源码

    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; 
    }
  • 相关阅读:
    【zookpeer】Failed to check the status of the service com.xxx.UserSerivce. No provider available for
    【solr】Spring data solr Document is missing mandatory uniqueKey field: id 解决
    【ssm】springmvc-spring-mybatis框架的搭建
    【jdbc】jdbc连接池理解
    【java基础】接口的理解
    【java基础】private protect的理解
    Single Number II
    Single Number I
    Candy
    Gas Station
  • 原文地址:https://www.cnblogs.com/doagain/p/14969326.html
Copyright © 2011-2022 走看看