Java hashcode浅析

散列码(hash code)是由对象导出的一个整型值。散列码是没有规律的,并且如果x和y是两个不同的对象,那么x的hash code与y的hash code基本上不会相同。对象间进行比较时,默认比较的是两个对象的hash code的值是否相同。

在Object类中定义了一个hashcode()的方法,因此每一个对象都有一个默认的hash code,其值为该对象存储的地址。

我们可以自己定义一个类来验证一下:

public class HashCodeDemo {

	public static void main(String[] args) {
		Node n1 = new Node("a",10);
		Node n2 = new Node("a",10);
		System.out.println("n1 equals n2?" + n1.equals(n2));
		System.out.println("n1 hashcode: " + n1.hashCode());
		System.out.println("n2 hashcode: " + n2.hashCode());

	}

}
class Node{
	String name;
	int age;
	
	Node(String _name, int _age){
		this.name = _name;
		this.age = _age;
	}
}
/*
输出:
n1 equals n2?false
n1 hashcode: 366712642
n2 hashcode: 1829164700
*/
可以发现,两个对象即使类型一样,内部属性也一样,其hashcode值也是不同的,这显然不符合我们使用equal()方法的需要。事实上,许多常用的对象内部都重写了hashcode方法。例如,Integer重写了hashcode,返回的是其内部的值;String类的hashcode也与其内部值有关,实现如下:

public int hashCode() {

        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
我们也可以通过一个例子来验证:

public class HashCodeDemo {

	public static void main(String[] args) {
		Integer i1 = Integer.valueOf(3);
		Integer i2 = Integer.valueOf(3);
		System.out.println("i1 equals i2?" + i1.equals(i2));
		System.out.println("i1 hashcode: " + i1.hashCode());
		System.out.println("i2 hashcode: " + i2.hashCode());

		String s1 = "STR";
		String s2 = "STR";
		System.out.println("s1 equals s2?" + s1.equals(s2));
		System.out.println("s1 hashcode: " + s1.hashCode());
		System.out.println("s2 hashcode: " + s2.hashCode());
	}

}
/*
输出:
i1 equals i2?true
i1 hashcode: 3
i2 hashcode: 3
s1 equals s2?true
s1 hashcode: 82449
s2 hashcode: 82449
*/
我们在定义类的时候也可以自己来实现其hashcode方法,且eclipse能够根据类的属性,自动生成其的hashcode方法:

public class HashCodeDemo {

	public static void main(String[] args) {
		NodeWithHash nw1 = new NodeWithHash("a",10);
		NodeWithHash nw2 = new NodeWithHash("a",10);
		System.out.println("nw1 equals nw2?" + nw1.equals(nw2));
		System.out.println("nw1 hashcode: " + nw1.hashCode());
		System.out.println("nw2 hashcode: " + nw2.hashCode());

	}

}
class NodeWithHash{
	String name;
	int age;
	
	NodeWithHash(String _name, int _age){
		this.name = _name;
		this.age = _age;
	}
	
	@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;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		NodeWithHash other = (NodeWithHash) 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;
	}
}

/*
输出:
nw1 equals nw2?true
nw1 hashcode: 1368
nw2 hashcode: 1368
*/






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章