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
*/






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