java源码之ArrayList.remove()&&removeAll(),
分享于 点击 49394 次 点评:278
java源码之ArrayList.remove()&&removeAll(),
java源码之ArrayList.remove&&removeAll
- 抛出问题
- 查看问题
- 结论
抛出问题
在使用ArrayList做一个发牌操作时,使用removeAll去删除已发的棋牌,比如已发【一万,二筒】,此时用removeALL去将剩余牌队列中的这两张牌删除,发现会将剩余牌中的所有【一万,二筒】全部删除,用remove去依次删除【一万】和【二筒】则只会删除一张【一万】和【二筒】;
查看问题
removeAll: 查看源码后发现removeAll会将所有eq的对象全部移除。
ArrayList.java
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
remove: 查看源码发现,会将list中第一个与删除对象eq的对象删除。
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;
}
结论
这里不能用removeAll的方式进行删除,因为我重写了实体的equals方法,【一筒@123】和【一筒@234】的equals值时相同的,所以用removeAll会同时删掉,这里可以用remove方式一个个删除,但是注意:此处因为是从list[0]开始发牌,所有可以用remove,如果是从末尾开始的,用remove则有问题,因为你要移除的是排在最后的【一筒】,但是你remove掉的是list中的第一个【一筒】;
相关文章
- 暂无相关文章
用户点评