马上结贴,ArrayList如何移除所有元素 removeAllpublic boolean removeAll(Collection<?> c)按理说应该是一个不带任何参数void返回类型的方法。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 ArrayList list=new ArrayList();list.clear();list=null; elementData = null.elementData = new Object[]; elementData = new Object[]; removeAllboolean removeAll(Collection<?> c)从列表中移除指定 collection 中包含的其所有元素(可选操作)。 指定者:接口 Collection<E> 中的 removeAll参数:c - 包含从此列表中移除的元素的 collection 返回:如果此列表由于调用而发生更改,则返回 true void clear() 回复内容太短了! clear()移除所有元素removeAll(Collection <?> c) 移除指定 collection 中包含的所有元素 有清空需求,表示这个容器还有他用,置为null后不是还要再实例化一个新容器实例吗?个人选择clear(); =================================请问一下。clear()又是怎么实现的?不还是把数据一个一个的设置为null. 多的话clear();少的话remove();最简单的办法赋值为null; ArrayList arrayList = new ArrayList();arrayList.add("a");arrayList.add("b");Iterator it = arrayList.iterator();while(it.hasNext()){ it.remove();} 刚看了ArrayList的源码,确实是这样。置null还是clear()时间消耗差异是微乎其微的,都可以选择。谢谢13L指出。 ===============================remove()又是怎么实现的,我发现JAVA虽然是开源的,同志们都不喜欢看源码。这与JAVA框架有关吧。也许你们做的是WEB开发,不在乎这些东西。我还没有做过一个像样的WEB项目。也许下一个项目是一个WEB项目,但JAVA基础的东西,源码有空还是要看一下。 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()还是要看需求然后选择使用的。 removeAll才是正解,是真正剔除所有的元素.clear()是将所有元素都变成null,但是还是有元素赋值为空,原来的对象仍然没变,如果其它地方引用该ArrayList,概念上仍然有元素 =================================================在之前我写了两个:elementData = null. elementData = new Object[];如果你需要保留容器,可以用new Object[];除此之外还保留了一个modCount值,size置0。还有,我一开始说的都是指重写ArrayList。而不是使用。 =========================================是的,有元素,但你无法使用,size=0。就告诉你,没有什么元素。 继承关系:ArrayList-->AbstractList-->AbstractCollectionremoveAll方法是在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 remove(int index) 移除此列表中指定位置上的元素。remove(Object o) 移除此列表中首次出现的指定元素(如果存在)。removeAll(Collection<?> c) 从列表中移除指定 collection 中包含的其所有元素(可选操作)。 补充说明:以上只是我分析的这两个方法的执行细节。从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; } 如果removeAll和clear功能一样的话,那要clear干吗呢?我觉得从字面上来说,应该是clear更加干净吧 ArrayList的实现里面是一个数组,然后有个int size,表示这个数组前面size个元素是这个ArrayList 里的元素。clear()的动作就是把前面size个元素都设为null(这样gc可以回收),再把size设为0。clearAll()返回的那个boolean很有用场的,因为你要求它remove的那堆东西,其实原来的ArrayList里可能一个也没有,这时removeAll其实什么事都没干,那它就返回false。只有真的删了什么了,才会返回true。 我只是说本质上的基本操作是一样的,都是使其中的引用为NULL如果从语义上讲,clear就是清空列表元素,removeAll就是集合A-B,如果A与B没有交集,就返回false,否则返回true 如果自身移除.A.removeAll(A);个人认为效率不如clear.因为clear不需要判断 一个outputStream的write方法的问题? 请教各位高手:用Eclipse做图形界面能否实现对按钮、标签的拖动? 大家帮我看看相互传递的时候,为什么为null呢 Invalid path, \bin\javac.exe -classpath thinking in java 把我看郁闷了大家帮忙吧 以后要用java 前辈们帮忙推荐几本好书 这段代码的同步总是无法实现,求帮助 swing 菜鸟入门小问题 java UDP server端接收消息会有上次的消息 java的jdk环境变量配好,但是不能使用。 一个关于关于泛型的Dmeo疑问 数据结构-哈希表问题
list.clear();
list=null;
elementData = new Object[];
boolean removeAll(Collection<?> c)从列表中移除指定 collection 中包含的其所有元素(可选操作)。 指定者:
接口 Collection<E> 中的 removeAll
参数:
c - 包含从此列表中移除的元素的 collection
返回:
如果此列表由于调用而发生更改,则返回 true
回复内容太短了!
removeAll(Collection <?> c) 移除指定 collection 中包含的所有元素
个人选择clear();
=================================
请问一下。clear()又是怎么实现的?
不还是把数据一个一个的设置为null.
少的话remove();
最简单的办法赋值为null;
arrayList.add("a");
arrayList.add("b");
Iterator it = arrayList.iterator();
while(it.hasNext()){
it.remove();
}
置null还是clear()时间消耗差异是微乎其微的,都可以选择。
谢谢13L指出。
remove()又是怎么实现的,我发现JAVA虽然是开源的,同志们都不喜欢看源码。
这与JAVA框架有关吧。也许你们做的是WEB开发,不在乎这些东西。
我还没有做过一个像样的WEB项目。
也许下一个项目是一个WEB项目,但JAVA基础的东西,源码有空还是要看一下。
我觉得本来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。而不是使用。
是的,有元素,但你无法使用,size=0。就告诉你,没有什么元素。
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
移除此列表中指定位置上的元素。remove(Object o)
移除此列表中首次出现的指定元素(如果存在)。removeAll(Collection<?> c)
从列表中移除指定 collection 中包含的其所有元素(可选操作)。
补充说明:以上只是我分析的这两个方法的执行细节。从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;
}
和clear功能一样的话,
那要clear干吗呢?
我觉得从字面上来说,应该是clear更加干净吧
我只是说本质上的基本操作是一样的,都是使其中的引用为NULL
如果从语义上讲,clear就是清空列表元素,removeAll就是集合A-B,如果A与B没有交集,就返回false,否则返回true
A.removeAll(A);
个人认为效率不如clear.
因为clear不需要判断