爲什麼要重寫equals()和hashcode()
在java裏集合類是使用十分頻繁的數據類型,Collection類中定義了一個方法是.contains(),不知道小夥伴們是否遇到過使用.contains()一直返回false,明明某個元素就在集合中的情況,反正我是遇到了。。。
那爲什麼會出現這種情況呢?其實Collection實現contains方法是通過調用equals()來將參數和集合中的每個元素進行比較的。那麼問題來了,對於我們自己寫的可變類型的類,若沒用重寫equals方法的話,就會出問題。看下面這個例子:
class Vertex{
private String name;
public Vertex(String vertex) {
name = vertex;
}
public void setName(String cString) {
name = cString;
}
public String getName() {
return name;
}
}
public static void main(String[] args)
{
String nString = "hhhh";
Vertex vertex = new Vertex(nString);
Vertex vertex2 = new Vertex(nString);
if ( vertex.equals(vertex2))
System.out.println("true");
else {
System.out.println("false");
}
vertex2.setName("hhhhh");
if ( vertex.equals(vertex2))
System.out.println("true");
else {
System.out.println("false");
}
}
上述代碼運行的結果按道理來說應該是true和false對吧,但其實是false和false。
那好,我們對class Vertex作出修改,重寫它的equals()和hashcode()方法,想偷懶的同學也可以用eclipse自動生成,但要確保滿足等價性,也就是對稱,自反,傳遞。生成方法也是右鍵source–>Generate equals() and hashcode(),變成如下這樣,也就是加上了equals和hashcode以後:
class Vertex{
private String name;
public Vertex(String vertex) {
name = vertex;
}
public void setName(String cString) {
name = cString;
}
public String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
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;
Vertex other = (Vertex) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
然後我們在運行,這時候打印輸出纔是true和false了。
所以,如果你要用contains()方法,就必須得重寫equals和hashcode,這裏我只是舉例個例子,想了解更多的小夥伴可以去找其他博客看看或者直接看collection的接口方法的實現。