使用java的人都知道,如果覆蓋了Object的equals方法,那么必須要覆蓋hashCode方法,并且如果兩個對象用equals方法比較返回true,那么這兩個對象hashCode返回的值也必須是相等的,并且對于同一個對象,equals方法需要比較的屬性值沒有被修改,那么每次調用hashCode返回的值應該是一致的。
那么為什么需要這樣呢,是不是所有的對象在覆蓋Object的equal方法時都需要覆蓋hashCode方法呢?下面以一個實例來說明該問題:
public class HashTest


{
@Test
public void testEqualAndHash()

{
Map<HashObject, String> map = new HashMap<HashObject, String>();
for(int i = 0; i < 10; i++)

{
HashObject o = new HashObject();
o.setId(i);
o.setIdCard("id_" + i);
o.setName("name_" + i);
o.setAddress("address_" + i);
map.put(o, o.getName());
System.out.println();
}
HashObject o = new HashObject();
o.setId(0);
o.setIdCard("id_" + 0);
o.setName("name_" + "zhangsan");
String v = map.put(o, o.getName());

/**//* 未實現hashcode方法,調用map的put方法將不會返回舊值,而是返回null */
System.out.println("v:" + v);
System.out.println("size:" + map.size());
}
}

public class HashObject


{
private Integer id;
private String name;
private String idCard;
private String address;
public Integer getId()

{
return id;
}
public void setId(Integer id)

{
this.id = id;
}
public String getName()

{
return name;
}
public void setName(String name)

{
this.name = name;
}
public String getIdCard()

{
return idCard;
}
public void setIdCard(String idCard)

{
this.idCard = idCard;
}
public String getAddress()

{
return address;
}
Object o = null;
public void setAddress(String address)

{
this.address = address;
}
public boolean equals(Object o)

{
if(this == o)
return true;
HashObject x = (HashObject) o;
if(x.getIdCard().equals(this.idCard))
return true;
return false;
}
// public int hashCode()
// {
//
// return 17 * 37 + this.idCard.hashCode();
//
// }
}關閉與開啟HashObject的hashCode方法的執行結果
v:null
size:11
----------------------
v:name_0
size:10
那么為什么會這樣呢,讓我們看看
1
public V put(K key, V value)
{
2
if (key == null)
3
return putForNullKey(value);
4
/**//*對key的hashcode做hash運算*/
5
int hash = hash(key.hashCode());
6
/**//*獲得key對應的Entry的索引位置*/
7
int i = indexFor(hash, table.length);
8
for (Entry<K,V> e = table[i]; e != null; e = e.next)
{
9
Object k;
10
/**//*HashMap采用鏈表來解決hashcode沖突,從這里可以看出,只有hashcode相等,且equals或者地址相等,HashMap才認為對象是相同的*/
11
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
{
12
V oldValue = e.value;
13
e.value = value;
14
e.recordAccess(this);
15
return oldValue;
16
}
17
}
18
19
modCount++;
20
addEntry(hash, key, value, i);
21
return null;
22
} HashMap的實現就一目了然了。HashMap采用Entry數組作為存儲<key,value>的數據結構,數組的索引是同過對key的hashcode做hash運算獲得的,HashMap采用鏈表來解決hash沖突問題。下面讓我們看看HashMap的put方法實現:
posted on 2012-08-16 18:39
zhangxl 閱讀(423)
評論(0) 編輯 收藏