java中的对象自动继承Object类,而Object类实现了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()已自动实现为不同的对象生成不同的hashCode,所以,当我们创建一个新的类时,即使以这个类为基准创建了两个完全相同的对象(对象中的元素完全相同),这两个相同对象的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容器会根据Key的hashCode,将不同hashCode对象(即hashCode()不同的对象而非equals()不同的对象)散列到不同的位置,这时候在Hash容器中应用这些对象时会出现错误。所以,在覆盖equals()方法时必须覆盖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中的对象自动继承Object类,而Object类实现了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()已自动实现为不同的对象生成不同的hashCode,所以,当我们创建一个新的类时,即使以这个类为基准创建了两个完全相同的对象(对象中的元素完全相同),这两个相同对象的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容器会根据Key的hashCode,将不同hashCode对象(即hashCode()不同的对象而非equals()不同的对象)散列到不同的位置,这时候在Hash容器中应用这些对象时会出现错误。所以,在覆盖equals()方法时必须覆盖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
新闻热点
疑难解答