在实际项目中我们通常会有一个需求就是:想知道在一个列表中是否包含某一个对象
这里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)函数。