谁能解释一下
remove()
的 ArrayList
是如何工作的?
public class ListTest {
public static void main(String[] args) {
List list = new ArrayList();
for(int i=0;i<10;i++)
{
list.add(i);
}
System.out.println("Size of list before removing :"+list.size());
for(int i=0;i<list.size();i++)
{
list.remove(i);
}
System.out.println("Size of list after removing all elements :"+list.size());
}
}
输出
删除前列表的大小:10
删除所有元素后列表的大小:5
我做错了什么?
list.remove(i);
移动被删除元素后面的所有元素的索引。因此,在调用 list.remove(0)
后,位置 1 处的前一个元素将移动到位置 0,并且循环将永远不会删除它,因为 i 会递增。正如您所看到的,您的循环只会删除一半的元素。
此循环将删除所有元素:
while(list.size()>0)
{
list.remove(0);
}
要在迭代集合时安全地从集合中删除,您应该使用迭代器。例如: 列出名称 = ....
Iterator<Integer> i = names.iterator();
while (i.hasNext()) {
Integer s = i.next();
// must be called before you can call i.remove() // Do something i.remove(); }
根据文档删除数组列表
集合包含一个或多个这样的元素。 集合,如果存在(可选操作)。更正式地说,如果集合包含一个或多个这样的元素,则删除 (o==null ? e==null : o.equals(e)) 的元素。
这意味着如果在依赖 equals() 的情况下使用它,它会删除第一个匹配出现的实例。
删除列表中指定位置的元素。任意移动 左侧的后续元素(从索引中减去 1)。
如上所述,从 ArrayList#remove 文档中可以看出,删除元素后 ArrayList 会自行调整大小,因此 ArrayList 实际上每次都会缩小,因此 FOR 循环只运行了一半的时间。
for(int i=0;i<list.size();i++)
{
System.out.println(i);
list.remove(i);
}
输出:
0
1
2
3
4
如果您检查
remove
是为了理解目的,那么没关系,否则您可以考虑使用ArrayList#clear
,这将令人信服地一次性清空您的ArrayList
。
另外,检查
ArrayList#remove
的重载方法,它允许您使用索引以及实际元素本身来删除元素,但在每种删除情况下,ArrayList 都会调整大小。
希望这有帮助!
因为
ArrayList
是一个动态调整大小的数组数据结构,这意味着它被实现为具有初始(默认)固定大小的数组。当它被填满时,数组将扩展到双倍大小。此操作成本较高,所以要尽可能少。
int newCapacity = (oldCapacity * 3)/2 + 1;
当您从
ArrayList
中删除元素时 - 他不会缩小尺寸。如果您想在删除项目后刷新内存,请使用
public void trimToSize()
此方法将此
ArrayList
实例的容量修剪为列表的当前大小。应用程序可以使用此操作来最小化 ArrayList
实例的存储。
因为 ArrayList 本质上是动态的。它的删除函数必须维护此属性,并且每次调用时都会动态减小 ArrayList 的大小。 删除只是将 List 中的元素移动一个索引,以便每次删除该元素并减少列表的大小。
列表的大小不是静态,每次从列表中删除元素时它都会不断减小。在你的情况下,最初列表的大小是 10。当你从列表中删除第一个元素时,大小减少到 9。当循环中的 i = 4 时,列表的大小将为 5。现在 i 的进一步增加将违反循环的条件
i< list.size()
因此,当列表大小仍为 5 时,循环将在那里终止。
只需在删除的 for 循环中添加下面提到的单行即可更好地理解。
System.out.println("list size is :"+list.size() +" and i is "+i);