看一个判断列表相等的例子,代码如下:
public static void main(String[] args) {
ArrayList<String> strs1 = new ArrayList<String>();
strs1.add("A");
Vector<String> strs2 = new Vector<String>();
strs2.add("A");
System.out.println(strs1.equals(strs2));
}
一个是 ArrayList,一个是 Vector,结果肯定不相等的!但事实上结果却是两者相等的。
我们来详细分析下为什么结果为 true。首先两者都是实现了 List 接口,都继承了 AbstractList 抽象类,而equals方法就是在 AbstractList 中定义的,代码如下:
public boolean equals(Object o) {
if (o == this)
return true;
// 是否是 List 列表,只要实现 List 接口即可
if (!(o instanceof List))
return false;
// 通过迭代器访问 list 中所有元素
ListIterator<E> e1 = listIterator();
ListIterator e2 = ((List) o).listIterator();
// 遍历两个 list 的元素进行比较
while(e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
// 发现不相等就退出
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
// 判断长度是否也相等
return !(e1.hasNext() || e2.hasNext());
}
在equals方法中只关心是否实现了 List 接口,并不关心具体的实现类。只要所有元素都相等,且长度相同就表示两个 List 是相等的。所以上面结果为 true 也就能理解了。
备注:其它的集合类型,如Set、Map等与此相同。
参考文献:《编写高质量代码:改善Java程序的151个建议》的建议69。