java中的hashCode方法是将一个字符串转换成数字。
public int hashCode() { int h = hash; int len = count; if (h == 0 && len > 0) { int off = offset; char val[] = value; for (int i = 0; i < len; i++) { h = 31*h + val[off++]; } hash = h; } return h; }
然后将多个属性 乘以一个系数,再进行累加。
@Override public int hashCode() { // TODO Auto-generated method stub return name.hashCode() * 37 + age; }
HashMap中通过一些位运算来计算hash值
static int hash(int h) { // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
----------------------------
hashCode方法的存在是为了减少equals方法的调用次数,从而提高程序效率。
HashMap的put方法先比较hash值再用equals判断是否相同
如果hash值相同,equals不同,则代表着hash冲突,会覆盖冲突的hash值。
理解hash冲突的一个实际意义是
如果对象中的数据易变,则最好在equals方法和hashCode方法中不要依赖于该字段。
不要在put了一个对象后改变其hashCode中的属性
package com.tristan; import java.util.HashMap; import java.util.HashSet; import java.util.Set; class People { private String name; private int age; public People(String name, int age) { this.name = name; this.age = age; } public void setAge(int age) { this.age = age; } @Override public int hashCode() { // TODO Auto-generated method stub return name.hashCode() * 37 + age; } @Override public boolean equals(Object obj) { // TODO Auto-generated method stub return this.name.equals(((People) obj).name) && this.age == ((People) obj).age; } } public class HashConflict { public static void main(String[] args) { People p1 = new People("Jack", 12); System.out.println(p1.hashCode()); HashMap<People, Integer> hashMap = new HashMap<People, Integer>(); hashMap.put(p1, 1); p1.setAge(13); System.out.println(hashMap.get(p1)); } }
参考 http://www.cnblogs.com/dolphin0520/p/3681042.html