在實際項目中我們通常會有一個需求就是:想知道在一個列表中是否包含某一個對象
這里ArrayList表、HashSet表和HashMap表都提供了一個contains(obj)方法,
下面說一下兩個列表contains(obj)方法的實現原理。
ArrayList表:
先遍歷表中每個元素(對象),然后對每個元素執行一個equals(obj)方法,該方法返回
一個布爾值。然而,通常我們查詢的時候並不會將一個對象的所有屬性值都輸入,可能
只輸入一個具有代表性的屬性值,比如name屬性,這個時候就要我們來修改equals(obj)
方法了,在內部if語句比較的時候只比較obj.name屬性值和當前列表元素的name屬性值。
public boolean equals(Object obj) {
if (this == obj)
return true; //比較對象和當前元素相同,返回true
if (obj == null)
return false; //比較對象為空,返回false
if (!(obj instanceof Courses))
return false; //比較對象類型和當前元素不同,返回false
Courses other = (Courses) obj;
if (name == null) {
if (other.name != null)
return false; //當前元素name為空,而比較對象name不為空,返回false
} else if (!name.equals(other.name))
return false; //當前元素name和比較對象name不相同,返回false
return true; //排除以上因素后,該函數才返回true
}
HashSet表:
值得一提的是,HashSet表的contains(obj)方法實現,不僅要比較屬性值字段是否匹配,還要
比較哈希碼值(經過哈希算法返回的一個int型數據),兩者都為true,contains(obj)方法才返
回true。於是我們就還要再重寫一下表內對象的hashCode()函數來只返回特定屬性值(name)
的哈希碼值。
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
注意,這是eclipse軟件生成的hashCode()函數,只返回name屬性的哈希碼值,其實函數內部
真正有意義的只有黑色加粗的這個hashCode()函數,這個函數的具體算法我們不做深究,result只
是對name的哈希碼值作進一步處理。切記,藍色的hashCode()函數是我們自己定義的,而黑色加粗
的hashCode()函數是引自java的哈希碼算法函數,不要搞混了!!!
有興趣的同學可以看一下哈希算法是怎么實現的~~~
HashMap表:
Map表由於是鍵值對的形式,所以就有兩種contains()方法:containsKey(Key)和containsValue(obj)
containsKey(Key)方法很明顯,傳入一個Key值,然后進行鍵值的匹配。
而containsVaule(obj),由於是一個對象,匹配的時候會根據具體屬性來匹配,這就需要重寫指定屬性例如
name的equals(obj)方法。另外提一點,containsVaule(obj)里面的obj可以這樣寫new Course(null,name),
因為比較的時候只比較了obj.name屬性,所以id屬性可以索性為空(null)!
還有個方法內部實現也用到equals(obj),list.indexOf(obj),將obj與List列表的每一項,用equal(obj)逐個比較,
當然也只是比較特定屬性,當equals()方法返回true時,將此項的索引值返回給indexOf(obj)函數。