马上结贴,ArrayList如何移除所有元素

孤尽JavaSea 2010-03-05 01:46:15
removeAll
public boolean removeAll(Collection<?> c)

按理说应该是一个不带任何参数
void返回类型的方法。
...全文
20194 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
zx8813443 2010-03-06
  • 打赏
  • 举报
回复
引用 29 楼 java_gannbare 的回复:
如果removeAll
和clear功能一样的话,
那要clear干吗呢?
我觉得从字面上来说,应该是clear更加干净吧


我只是说本质上的基本操作是一样的,都是使其中的引用为NULL
如果从语义上讲,clear就是清空列表元素,removeAll就是集合A-B,如果A与B没有交集,就返回false,否则返回true
shizheyiyi 2010-03-06
  • 打赏
  • 举报
回复
arrayList.clear()
黑呼乎 2010-03-06
  • 打赏
  • 举报
回复
学习了,感觉19L说的对。
zx8813443 2010-03-06
  • 打赏
  • 举报
回复
引用 32 楼 java_gannbare 的回复:
如果自身移除.
A.removeAll(A);
个人认为效率不如clear.
因为clear不需要判断

那必须的
孤尽JavaSea 2010-03-06
  • 打赏
  • 举报
回复
如果自身移除.
A.removeAll(A);
个人认为效率不如clear.
因为clear不需要判断
reve123456 2010-03-05
  • 打赏
  • 举报
回复
ArrayList的实现里面是一个数组,然后有个int size,表示这个数组前面size个元素是这个ArrayList 里的元素。clear()的动作就是把前面size个元素都设为null(这样gc可以回收),再把size设为0。

clearAll()返回的那个boolean很有用场的,因为你要求它remove的那堆东西,其实原来的ArrayList里可能一个也没有,这时removeAll其实什么事都没干,那它就返回false。只有真的删了什么了,才会返回true。
孤尽JavaSea 2010-03-05
  • 打赏
  • 举报
回复
如果removeAll
和clear功能一样的话,
那要clear干吗呢?
我觉得从字面上来说,应该是clear更加干净吧
zx8813443 2010-03-05
  • 打赏
  • 举报
回复
引用 26 楼 canghaiguzhou 的回复:
继承关系:ArrayList-->AbstractList-->AbstractCollection
removeAll方法是在AbstractCollection中定义的,ArrayList继承了这个方法
iterator()方法在AbstractCollection类中定义为抽象方法(这里用到了模板方法设计模式,iterator()方法作为模板在其他方法中得到调用,子类只需覆盖此模板方法即可。)这里应该还有一个模板类Iterator,Iterator的行为取决于你的具体实现
Java code//AbstractCollectionpublicboolean removeAll(Collection<?> c) {boolean modified=false;
Iterator<?> e= iterator();while (e.hasNext()) {if (c.contains(e.next())) {
e.remove();
modified=true;
}
}return modified;
}

在AbstractList中实现了iterator()这个模板方法,简单的返回一个迭代器的实现
Java code//AbstractListpublic Iterator<E> iterator() {returnnew Itr();
}//remove方法,需要在AbstractList的子类中实现public E remove(int index) {thrownew UnsupportedOperationException();
}

这个迭代器Itr作为AbstractList私有内部类去实现

Java codeprivateclass Itrimplements Iterator<E> {
..../*这个字段的意思,根据sun的英文注释,我的理解是,记录了列表的结构性改变次数,如果迭代器希望防止对列表结构的并发性修改,就得在每次改变列表结构的列表操作中,使该字段仅仅增加1;
这里Iterator的实现,将结构变化次数赋给expectedModCount保存,*/int expectedModCount= modCount;publicvoid remove() {if (lastRet==-1)thrownew IllegalStateException();
checkForComodification();try {//这里实际采用AbstractList的子类中的remove方法来删除元素 AbstractList.this.remove(lastRet);if (lastRet< cursor)
cursor--;
lastRet=-1;/*如果子类中想提供一个快速失败的迭代器,必须在能改变列表结构的方法中仅使modCount增加1,这样,经过上边的AbstractList.this.remove(lastRet)操作(实际上是ArrayList的remove方法,ArrayList提供快速失败的迭代器),modCount增加了,需要重新赋给expectedModCount保存起来,因为这次结构修改是迭代器自己做的,不属于并发的修改。*/
expectedModCount= modCount;
}catch (IndexOutOfBoundsException e) {thrownew ConcurrentModificationException();
}
}/*检测结构变化次数在迭代操作中是否有变,如果有变,则说明在迭代过程中存在并发性的列表结构修改,抛出ConcurrentModificationException*/finalvoid checkForComodification() {if (modCount!= expectedModCount)thrownew ConcurrentModificationException();
}


....

}Java code//ArrayList中的remove方法,覆盖了AbstractList中的remove方法public E remove(int index) {
RangeCheck(index);

modCount++;//增加结构化修改次数 E oldValue= (E) elementData[index];/*获得被删元素后面的一个元素的下标,从这个元素开始一直到最后,应该向前移一位*/int numMoved= size- index-1;if (numMoved>0)//将元素前移 System.arraycopy(elementData, index+1, elementData, index,
numMoved);//将最后一个元素置为null,失去引用的对象由gc收集 elementData[--size]=null;// Let gc do its workreturn oldValue;
}


结论:ArrayList中的clear方法与removeAll方法本质上都是使其中的引用变为null


补充说明:以上只是我分析的这两个方法的执行细节。

从removeAll方法的实现来看,这个方法是迭代自己的列表中的每一个元素,检查是否在指定集合中存在,如果存在则删除,如果你学过集合论的话,就是集合中A-B的关系,将A中存在和B中相同的元素剔除

//AbstractCollection
public boolean removeAll(Collection<?> c) {
boolean modified = false;
Iterator<?> e = iterator();
while (e.hasNext()) {
if (c.contains(e.next())) {
e.remove();
modified = true;
}
}
return modified;
}


星辰企业 2010-03-05
  • 打赏
  • 举报
回复
remove(int index)
移除此列表中指定位置上的元素。

remove(Object o)
移除此列表中首次出现的指定元素(如果存在)。

removeAll(Collection<?> c)
从列表中移除指定 collection 中包含的其所有元素(可选操作)。
zx8813443 2010-03-05
  • 打赏
  • 举报
回复
继承关系:ArrayList-->AbstractList-->AbstractCollection
removeAll方法是在AbstractCollection中定义的,ArrayList继承了这个方法
iterator()方法在AbstractCollection类中定义为抽象方法(这里用到了模板方法设计模式,iterator()方法作为模板在其他方法中得到调用,子类只需覆盖此模板方法即可。)这里应该还有一个模板类Iterator,Iterator的行为取决于你的具体实现

//AbstractCollection
public boolean removeAll(Collection<?> c) {
boolean modified = false;
Iterator<?> e = iterator();
while (e.hasNext()) {
if (c.contains(e.next())) {
e.remove();
modified = true;
}
}
return modified;
}


在AbstractList中实现了iterator()这个模板方法,简单的返回一个迭代器的实现

//AbstractList
public Iterator<E> iterator() {
return new Itr();
}
//remove方法,需要在AbstractList的子类中实现
public E remove(int index) {
throw new UnsupportedOperationException();
}


这个迭代器Itr作为AbstractList私有内部类去实现


private class Itr implements Iterator<E> {
....
/*这个字段的意思,根据sun的英文注释,我的理解是,记录了列表的结构性改变次数,如果迭代器希望防止对列表结构的并发性修改,就得在每次改变列表结构的列表操作中,使该字段仅仅增加1;
这里Iterator的实现,将结构变化次数赋给expectedModCount保存,*/
int expectedModCount = modCount;

public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();

try {
//这里实际采用AbstractList的子类中的remove方法来删除元素
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
/*如果子类中想提供一个快速失败的迭代器,必须在能改变列表结构的方法中仅使modCount增加1,这样,经过上边的AbstractList.this.remove(lastRet)操作(实际上是ArrayList的remove方法,ArrayList提供快速失败的迭代器),modCount增加了,需要重新赋给expectedModCount保存起来,因为这次结构修改是迭代器自己做的,不属于并发的修改。*/
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
/*检测结构变化次数在迭代操作中是否有变,如果有变,则说明在迭代过程中存在并发性的列表结构修改,抛出ConcurrentModificationException*/
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}


....

}

//ArrayList中的remove方法,覆盖了AbstractList中的remove方法
public E remove(int index) {
RangeCheck(index);

modCount++;//增加结构化修改次数
E oldValue = (E) elementData[index];

/*获得被删元素后面的一个元素的下标,从这个元素开始一直到最后,应该向前移一位*/
int numMoved = size - index - 1;

if (numMoved > 0)
//将元素前移
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//将最后一个元素置为null,失去引用的对象由gc收集
elementData[--size] = null; // Let gc do its work

return oldValue;
}



结论:ArrayList中的clear方法与removeAll方法本质上都是使其中的引用变为null
liguang168 2010-03-05
  • 打赏
  • 举报
回复
引用 24 楼 beyond_cn 的回复:
输入个箭头什么都有了。。。

?????????????????????????
Beyond_cn 2010-03-05
  • 打赏
  • 举报
回复
输入个箭头什么都有了。。。
liguang168 2010-03-05
  • 打赏
  • 举报
回复
引用 21 楼 lliiqiang 的回复:
removeAll才是正解,是真正剔除所有的元素.

clear()是将所有元素都变成null,但是还是有元素

赋值为空,原来的对象仍然没变,如果其它地方引用该ArrayList,概念上仍然有元素

=========================================
是的,有元素,但你无法使用,size=0。就告诉你,没有什么元素。
liguang168 2010-03-05
  • 打赏
  • 举报
回复
引用 19 楼 tillperfect 的回复:
sodino 和 dinghun8leech 讨论了下 clear() 和直接将 list置为null有啥区别的问题。
我觉得本来12楼dinghun8leech说的是对的,但是他被sodino在13楼说的话给弄蒙了。

ArrayList源码里面,对clear()的确采取的是将元素一个一个的置为null,所以,
看上去,使用clear()似乎不如将list直接置为null快。

不过12楼dinghun8leech说了句话,这个容器可能还有他用。若真的还有他用,那就建议用clear()了,
这样省的再new 了。

请sodino注意下,clear()里面,是对list中的元素进行置null操作,但是list对象本身并不是null。所以,list=null 与 list.clear()还是要看需求然后选择使用的。


=================================================
在之前我写了两个:
elementData = null.
elementData = new Object[];
如果你需要保留容器,可以用new Object[];
除此之外还保留了一个modCount值,size置0。
还有,我一开始说的都是指重写ArrayList。而不是使用。
lliiqiang 2010-03-05
  • 打赏
  • 举报
回复
removeAll才是正解,是真正剔除所有的元素.

clear()是将所有元素都变成null,但是还是有元素

赋值为空,原来的对象仍然没变,如果其它地方引用该ArrayList,概念上仍然有元素
oyctzl 2010-03-05
  • 打赏
  • 举报
回复
arrayList.clear()
TillPerfect 2010-03-05
  • 打赏
  • 举报
回复
sodino 和 dinghun8leech 讨论了下 clear() 和直接将 list置为null有啥区别的问题。
我觉得本来12楼dinghun8leech说的是对的,但是他被sodino在13楼说的话给弄蒙了。

ArrayList源码里面,对clear()的确采取的是将元素一个一个的置为null,所以,
看上去,使用clear()似乎不如将list直接置为null快。

不过12楼dinghun8leech说了句话,这个容器可能还有他用。若真的还有他用,那就建议用clear()了,
这样省的再new 了。

请sodino注意下,clear()里面,是对list中的元素进行置null操作,但是list对象本身并不是null。所以,list=null 与 list.clear()还是要看需求然后选择使用的。
keeya0416 2010-03-05
  • 打赏
  • 举报
回复
引用 6 楼 luffyke 的回复:
removeAll
boolean removeAll(Collection <?> c)从列表中移除指定 collection 中包含的其所有元素(可选操作)。

指定者:
接口 Collection <E> 中的 removeAll
参数:
c - 包含从此列表中移除的元素的 collection
返回:
如果此列表由于调用而发生更改,则返回 true

说的很明白了
liguang168 2010-03-05
  • 打赏
  • 举报
回复
引用 15 楼 j_codeliving 的回复:
ArrayList arrayList = new ArrayList();
arrayList.add("a");
arrayList.add("b");
Iterator it = arrayList.iterator();
while(it.hasNext()){
  it.remove();
}

===============================
remove()又是怎么实现的,我发现JAVA虽然是开源的,同志们都不喜欢看源码。
这与JAVA框架有关吧。也许你们做的是WEB开发,不在乎这些东西。
我还没有做过一个像样的WEB项目。
也许下一个项目是一个WEB项目,但JAVA基础的东西,源码有空还是要看一下。
dinghun8leech 2010-03-05
  • 打赏
  • 举报
回复
引用 13 楼 liguang168 的回复:
请问一下。clear()又是怎么实现的?
不还是把数据一个一个的设置为null.

刚看了ArrayList的源码,确实是这样。
置null还是clear()时间消耗差异是微乎其微的,都可以选择。
谢谢13L指出。
加载更多回复(15)

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧