标签:
package com.wangzhu.map; import java.util.HashMap; /** * hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,<br/> * 这样的散列集合包括HashSet、HashMap以及HashTable。<br/> * 能否可以直接根据hashCode值判断两个对象是否相等呢?<br/> * 答案:肯定是不可以的,因为不同的对象可能会生成相同的hashCode值。<br/> * 虽然不能根据hashCode值判断两个对象是否相等,但是可以直接根据hashCode值判断两个对象不等,<br/> * 如果两个对象的hashCode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,则必须通过equals方法。<br/> * 也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashCode值必定相等。<br/> * 如果equals方法得到的结果为,则两个对象的hashCode值不一定不同; <br/> * 如果两个对象的hashCode值不等,则equals方法得到的结果必为;<br/> * 如果两个对象的hashCode值相等,则equals方法得到的结果未知。<br/> * * @author wangzhu * @date 2015-2-1下午11:22:42 * */ public class DemoMap2 { /** * @param args */ public static void main(String[] args) { Student stu = new Student(21, "John"); HashMap<Student, Integer> map = new HashMap<Student, Integer>(); map.put(stu, 1); System.out.println(map.get(stu));// 1 System.out.println(map.get(new Student(21, "John")));// 1 /** * 若Student只重写equals方法而没有没有重写hashCode方法时,则输出为null */ stu.setAge(22); System.out.println(map.get(stu));// null /** * 在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,<br/> * 那么对这同一个对象调用多次, hashCode方法必须始终如一地返回同一个整数。<br/> * * 设计hashCode()时最终稿的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。<br/> * 如果在将一个对象用put()添加进HashMap时产生一个hashCode值,而用get()取出时却产生另一个hashCode值,<br/> * 那么就无法获取该对象了。所以如果你的hashCode方法依赖于对象中易变的数据,用户就要当心了,<br/> * 因为此数据变化时,hashCode() 方法就会生成一个不同的散列码。<br/> */ } } class Student { int age; String name; public Student(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = (prime * result) + age; result = (prime * result) + ((name == null) ? 0 : name.hashCode()); return result; } /** * 重写时,需要让equals方法与hashCode方法始终在逻辑上保持一致性。 */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (this.getClass() != obj.getClass()) { return false; } Student other = (Student) obj; if (age != other.age) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } }
下面是HashMap中的put方法【JDK1.6】
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; }
备注:put方法是用来向HashMap中添加新的元素。从put方法的具体实现可知,其会先调用hashCode方法得到该元素的hashCode值【经过处理的】,然后查看其是否存在于table数组中,如果存在则调用equals方法来确定是否是存在该元素;如果存在,则更新value值,否则将新的元素添加到HashMap中。
下面是HashMap中的get方法【JDK1.6】
public V get(Object key) { if (key == null) return getForNullKey(); int hash = hash(key.hashCode()); for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }
备注:get方法是用来将HashMap中对应Key的值Value取出来。从get方法的具体实现可知,其会先调用hashCode方法得到该元素的hashCode值,然后查看其在table数组中是否存在,如果存在则调用equals方法来确定是Key对应的元素,并返回其Value,否则返回null。
重写equals()方法时,需要同时重写hashCode()方法
标签:
原文地址:http://www.cnblogs.com/xiaoxian1369/p/4266599.html