在写算法时遇到了这么一个需求:
用ArrayList去保存ArrayList,然后当作返回值返回。
里面那层ArrayList保存的是int数据,外面那层保存的是ArrayList。涉及到ArrayList的add和addAll还有remove操作。有这么一段代码:
//错误
if(root.left!=null){
ArrayList<Integer> templ = new ArrayList();
result.add(templ);
templ.addAll(rootList);
result.remove(rootList);
Traverse(root.left,templ);
}
//正确
if(root.left!=null){
ArrayList<Integer> templ = new ArrayList();
result.remove(rootList);
result.add(templ);
templ.addAll(rootList);
Traverse(root.left,templ);
}
其中result就是保存ArrayList的那个List。templ和rootList都是保存int数据的ArrayList。rootList和templ经验证是两个不同的对象,以上两种写法得到的结果却不同。
带着疑惑翻了一下源码才找到答案:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
以上是ArrayList的remove方法。第一个想到的就是可能equals被重写了,但是ArrayList的equals并没有重写,无意间打开AbstractList才真相大白:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator<?> e2 = ((List<?>) o).listIterator();
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());
}
简单说只要都是List然后每个元素相等就代表它们是equals的。(还是觉得==靠谱)