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; 
    }
  • 相关阅读:
    Anagram
    HDU 1205 吃糖果(鸽巢原理)
    Codeforces 1243D 0-1 MST(补图的连通图数量)
    Codeforces 1243C Tile Painting(素数)
    Codeforces 1243B2 Character Swap (Hard Version)
    Codeforces 1243B1 Character Swap (Easy Version)
    Codeforces 1243A Maximum Square
    Codeforces 1272E Nearest Opposite Parity(BFS)
    Codeforces 1272D Remove One Element
    Codeforces 1272C Yet Another Broken Keyboard
  • 原文地址:https://www.cnblogs.com/doagain/p/14969326.html
Copyright © 2011-2022 走看看