国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

關(guān)于Java覆蓋equals方法時(shí)必須覆蓋hashCode方法

2019-11-06 06:40:23
字體:
供稿:網(wǎng)友

java中的對象自動(dòng)繼承Object類,而Object類實(shí)現(xiàn)了equals方法和hashCode方法:

    /**     * Returns a hash code value for the object. This method is      * supported for the benefit of hashtables such as those PRovided by      * <code>java.util.Hashtable</code>.      * <p>     * The general contract of <code>hashCode</code> is:      * <ul>     * <li>Whenever it is invoked on the same object more than once during      *     an execution of a Java application, the <tt>hashCode</tt> method      *     must consistently return the same integer, provided no information      *     used in <tt>equals</tt> comparisons on the object is modified.     *     This integer need not remain consistent from one execution of an     *     application to another execution of the same application.      * <li>If two objects are equal according to the <tt>equals(Object)</tt>     *     method, then calling the <code>hashCode</code> method on each of      *     the two objects must produce the same integer result.      * <li>It is <em>not</em> required that if two objects are unequal      *     according to the {@link java.lang.Object#equals(java.lang.Object)}      *     method, then calling the <tt>hashCode</tt> method on each of the      *     two objects must produce distinct integer results.  However, the      *     programmer should be aware that producing distinct integer results      *     for unequal objects may improve the performance of hashtables.     * </ul>     * <p>     * As much as is reasonably practical, the hashCode method defined by      * class <tt>Object</tt> does return distinct integers for distinct      * objects. (This is typically implemented by converting the internal      * address of the object into an integer, but this implementation      * technique is not required by the      * Java<font size="-2"><sup>TM</sup></font> programming language.)     *     * @return  a hash code value for this object.     * @see     java.lang.Object#equals(java.lang.Object)     * @see     java.util.Hashtable     */    public native int hashCode();    /**     * Indicates whether some other object is "equal to" this one.     * <p>     * The <code>equals</code> method implements an equivalence relation     * on non-null object references:     * <ul>     * <li>It is <i>reflexive</i>: for any non-null reference value     *     <code>x</code>, <code>x.equals(x)</code> should return     *     <code>true</code>.     * <li>It is <i>symmetric</i>: for any non-null reference values     *     <code>x</code> and <code>y</code>, <code>x.equals(y)</code>     *     should return <code>true</code> if and only if     *     <code>y.equals(x)</code> returns <code>true</code>.     * <li>It is <i>transitive</i>: for any non-null reference values     *     <code>x</code>, <code>y</code>, and <code>z</code>, if     *     <code>x.equals(y)</code> returns <code>true</code> and     *     <code>y.equals(z)</code> returns <code>true</code>, then     *     <code>x.equals(z)</code> should return <code>true</code>.     * <li>It is <i>consistent</i>: for any non-null reference values     *     <code>x</code> and <code>y</code>, multiple invocations of     *     <tt>x.equals(y)</tt> consistently return <code>true</code>     *     or consistently return <code>false</code>, provided no     *     information used in <code>equals</code> comparisons on the     *     objects is modified.     * <li>For any non-null reference value <code>x</code>,     *     <code>x.equals(null)</code> should return <code>false</code>.     * </ul>     * <p>     * The <tt>equals</tt> method for class <code>Object</code> implements      * the most discriminating possible equivalence relation on objects;      * that is, for any non-null reference values <code>x</code> and     * <code>y</code>, this method returns <code>true</code> if and only     * if <code>x</code> and <code>y</code> refer to the same object     * (<code>x == y</code> has the value <code>true</code>).     * <p>     * Note that it is generally necessary to override the <tt>hashCode</tt>     * method whenever this method is overridden, so as to maintain the     * general contract for the <tt>hashCode</tt> method, which states     * that equal objects must have equal hash codes.      *     * @param   obj   the reference object with which to compare.     * @return  <code>true</code> if this object is the same as the obj     *          argument; <code>false</code> otherwise.     * @see     #hashCode()     * @see     java.util.Hashtable     */    public boolean equals(Object obj) {	return (this == obj);    }Object類中的hashCode()已自動(dòng)實(shí)現(xiàn)為不同的對象生成不同的hashCode,所以,當(dāng)我們創(chuàng)建一個(gè)新的類時(shí),即使以這個(gè)類為基準(zhǔn)創(chuàng)建了兩個(gè)完全相同的對象(對象中的元素完全相同),這兩個(gè)相同對象的hashCode也是不同的:

import java.util.Map;import java.util.Map.Entry;import com.google.common.base.Objects;import com.google.common.collect.Maps;public class Name {    String id;    Name(String id) {        this.id = id;    }    @Override    public boolean equals(Object obj) {        Name otherName = (Name) obj;        return Objects.equal(this.id, otherName.id);    }    @Override    public String toString() {        return this.getClass().getSimpleName() + "@" + this.id + "&" + this.hashCode();    }    public static void main(String[] args) {        Name n1 = new Name("zhao");        Name n2 = new Name("zhao");        System.err.println("n1.equals(n2) = " + n1.equals(n2));        Map<Name, Integer> map = Maps.newHashMap();        map.put(n1, 1);        map.put(n2, 2);        for (Entry<Name, Integer> entry : map.entrySet()) {            System.out.println(entry.getKey() + ":" + entry.getValue());        }        System.err.println(map.get(new Name("zhao")));    }}而Java中的Hash容器會(huì)根據(jù)Key的hashCode,將不同hashCode對象(即hashCode()不同的對象而非equals()不同的對象)散列到不同的位置,這時(shí)候在Hash容器中應(yīng)用這些對象時(shí)會(huì)出現(xiàn)錯(cuò)誤。所以,在覆蓋equals()方法時(shí)必須覆蓋hashCode()方法。

    /**     * Associates the specified value with the specified key in this map.     * If the map previously contained a mapping for the key, the old     * value is replaced.     *     * @param key key with which the specified value is to be associated     * @param value value to be associated with the specified key     * @return the previous value associated with <tt>key</tt>, or     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.     *         (A <tt>null</tt> return can also indicate that the map     *         previously associated <tt>null</tt> with <tt>key</tt>.)     */    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;    }

參考文章:

1、JDK源碼

2、http://www.cnblogs.com/wangliyue/p/4450747.html

3、http://www.cnblogs.com/happyPawpaw/p/3744971.html

Java中的對象自動(dòng)繼承Object類,而Object類實(shí)現(xiàn)了equals方法和hashCode方法:

    /**     * Returns a hash code value for the object. This method is      * supported for the benefit of hashtables such as those provided by      * <code>java.util.Hashtable</code>.      * <p>     * The general contract of <code>hashCode</code> is:      * <ul>     * <li>Whenever it is invoked on the same object more than once during      *     an execution of a Java application, the <tt>hashCode</tt> method      *     must consistently return the same integer, provided no information      *     used in <tt>equals</tt> comparisons on the object is modified.     *     This integer need not remain consistent from one execution of an     *     application to another execution of the same application.      * <li>If two objects are equal according to the <tt>equals(Object)</tt>     *     method, then calling the <code>hashCode</code> method on each of      *     the two objects must produce the same integer result.      * <li>It is <em>not</em> required that if two objects are unequal      *     according to the {@link java.lang.Object#equals(java.lang.Object)}      *     method, then calling the <tt>hashCode</tt> method on each of the      *     two objects must produce distinct integer results.  However, the      *     programmer should be aware that producing distinct integer results      *     for unequal objects may improve the performance of hashtables.     * </ul>     * <p>     * As much as is reasonably practical, the hashCode method defined by      * class <tt>Object</tt> does return distinct integers for distinct      * objects. (This is typically implemented by converting the internal      * address of the object into an integer, but this implementation      * technique is not required by the      * Java<font size="-2"><sup>TM</sup></font> programming language.)     *     * @return  a hash code value for this object.     * @see     java.lang.Object#equals(java.lang.Object)     * @see     java.util.Hashtable     */    public native int hashCode();    /**     * Indicates whether some other object is "equal to" this one.     * <p>     * The <code>equals</code> method implements an equivalence relation     * on non-null object references:     * <ul>     * <li>It is <i>reflexive</i>: for any non-null reference value     *     <code>x</code>, <code>x.equals(x)</code> should return     *     <code>true</code>.     * <li>It is <i>symmetric</i>: for any non-null reference values     *     <code>x</code> and <code>y</code>, <code>x.equals(y)</code>     *     should return <code>true</code> if and only if     *     <code>y.equals(x)</code> returns <code>true</code>.     * <li>It is <i>transitive</i>: for any non-null reference values     *     <code>x</code>, <code>y</code>, and <code>z</code>, if     *     <code>x.equals(y)</code> returns <code>true</code> and     *     <code>y.equals(z)</code> returns <code>true</code>, then     *     <code>x.equals(z)</code> should return <code>true</code>.     * <li>It is <i>consistent</i>: for any non-null reference values     *     <code>x</code> and <code>y</code>, multiple invocations of     *     <tt>x.equals(y)</tt> consistently return <code>true</code>     *     or consistently return <code>false</code>, provided no     *     information used in <code>equals</code> comparisons on the     *     objects is modified.     * <li>For any non-null reference value <code>x</code>,     *     <code>x.equals(null)</code> should return <code>false</code>.     * </ul>     * <p>     * The <tt>equals</tt> method for class <code>Object</code> implements      * the most discriminating possible equivalence relation on objects;      * that is, for any non-null reference values <code>x</code> and     * <code>y</code>, this method returns <code>true</code> if and only     * if <code>x</code> and <code>y</code> refer to the same object     * (<code>x == y</code> has the value <code>true</code>).     * <p>     * Note that it is generally necessary to override the <tt>hashCode</tt>     * method whenever this method is overridden, so as to maintain the     * general contract for the <tt>hashCode</tt> method, which states     * that equal objects must have equal hash codes.      *     * @param   obj   the reference object with which to compare.     * @return  <code>true</code> if this object is the same as the obj     *          argument; <code>false</code> otherwise.     * @see     #hashCode()     * @see     java.util.Hashtable     */    public boolean equals(Object obj) {	return (this == obj);    }Object類中的hashCode()已自動(dòng)實(shí)現(xiàn)為不同的對象生成不同的hashCode,所以,當(dāng)我們創(chuàng)建一個(gè)新的類時(shí),即使以這個(gè)類為基準(zhǔn)創(chuàng)建了兩個(gè)完全相同的對象(對象中的元素完全相同),這兩個(gè)相同對象的hashCode也是不同的:

import java.util.Map;import java.util.Map.Entry;import com.google.common.base.Objects;import com.google.common.collect.Maps;public class Name {    String id;    Name(String id) {        this.id = id;    }    @Override    public boolean equals(Object obj) {        Name otherName = (Name) obj;        return Objects.equal(this.id, otherName.id);    }    @Override    public String toString() {        return this.getClass().getSimpleName() + "@" + this.id + "&" + this.hashCode();    }    public static void main(String[] args) {        Name n1 = new Name("zhao");        Name n2 = new Name("zhao");        System.err.println("n1.equals(n2) = " + n1.equals(n2));        Map<Name, Integer> map = Maps.newHashMap();        map.put(n1, 1);        map.put(n2, 2);        for (Entry<Name, Integer> entry : map.entrySet()) {            System.out.println(entry.getKey() + ":" + entry.getValue());        }        System.err.println(map.get(new Name("zhao")));    }}而Java中的Hash容器會(huì)根據(jù)Key的hashCode,將不同hashCode對象(即hashCode()不同的對象而非equals()不同的對象)散列到不同的位置,這時(shí)候在Hash容器中應(yīng)用這些對象時(shí)會(huì)出現(xiàn)錯(cuò)誤。所以,在覆蓋equals()方法時(shí)必須覆蓋hashCode()方法。

    /**     * Associates the specified value with the specified key in this map.     * If the map previously contained a mapping for the key, the old     * value is replaced.     *     * @param key key with which the specified value is to be associated     * @param value value to be associated with the specified key     * @return the previous value associated with <tt>key</tt>, or     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.     *         (A <tt>null</tt> return can also indicate that the map     *         previously associated <tt>null</tt> with <tt>key</tt>.)     */    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;    }

參考文章:

1、JDK源碼

2、http://www.cnblogs.com/wangliyue/p/4450747.html

3、http://www.cnblogs.com/happyPawpaw/p/3744971.html


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 同心县| 南召县| 徐州市| 舟曲县| 色达县| 崇阳县| 忻州市| 大渡口区| 克东县| 黄梅县| 息烽县| 绍兴县| 财经| 韩城市| 广宁县| 沅江市| 庄浪县| 尚志市| 拉萨市| 利川市| 班戈县| 青龙| 云霄县| 犍为县| 凤冈县| 太原市| 鹤山市| 青铜峡市| 葫芦岛市| 郯城县| 鄂温| 慈利县| 潼关县| 宝应县| 普兰县| 峨边| 台北县| 铁力市| 沭阳县| 克山县| 府谷县|