hash冲突


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

猜你喜欢

转载自tristan-s.iteye.com/blog/2248086