Java 当我们删除元素时,ArrayList 的容量会减少吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23831157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does the capacity of ArrayList decrease when we remove elements?
提问by Santosh Pashupati
ArrayList have a default capacity of 10 objects. As the size exceeds 10 objects, an ArrayList will internally increase its capacity. Does the capacity decrease when we remove the object from ArrayList.
ArrayList 的默认容量为 10 个对象。当大小超过 10 个对象时,ArrayList 将在内部增加其容量。当我们从 ArrayList 中删除对象时,容量是否会减少。
If the ArrayList capacity doesn't decrease, could this lead to performance issues?
如果 ArrayList 容量没有减少,是否会导致性能问题?
采纳答案by John
It doesn't decrease this automatically. From the doc.
它不会自动减少这个。从文档。
public void trimToSize()
Trims the capacity of this ArrayList instance to be the list's current size. An application can use this operation to minimize the storage of an ArrayList instance.
将此 ArrayList 实例的容量修剪为列表的当前大小。应用程序可以使用此操作来最小化 ArrayList 实例的存储空间。
回答by Richard Tingle
There are several remove methods within arraylist, I will use the remove by index version as this example
arraylist中有几个remove方法,我将使用remove by index版本作为这个例子
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
The most important thing to note is that a new array is never created within elementData
so its size does not change, only elements are copied.
需要注意的最重要的一点是,永远不会在其中创建新数组,elementData
因此它的大小不会改变,只会复制元素。
If you need to reduce the capacity of the array list (which you usually won't) use trimToSize()
如果您需要减少数组列表的容量(通常不会)使用 trimToSize()
回答by dan.m was user2321368
The ArrayList offers a method, trimToSize(), that "Trims the capacity of this ArrayList instance to be the list's current size. An application can use this operation to minimize the storage of an ArrayList instance." See http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#trimToSize().
ArrayList 提供了一种方法,trimToSize(),“将这个 ArrayList 实例的容量修剪为列表的当前大小。应用程序可以使用此操作来最小化 ArrayList 实例的存储空间。” 请参阅http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#trimToSize()。
If any other methods do such an action silently, that would depend on the implementation provided with your JRE.
如果任何其他方法以静默方式执行此类操作,则取决于您的 JRE 提供的实现。
回答by Prabhaker A
do the the capacity decrease when we remove the object from ArrayList.
do the the capacity decrease when we remove the object from ArrayList.
The answer is simply no.If you observe source code of the ArrayListclass, you will get the answer.
There is no operation to decrease capacity of ArrayList's remove()
method.
答案是否定的。如果您观察ArrayList类的源代码,您将得到答案。
没有减少 ArrayListremove()
方法容量的操作。
回答by Robert3452
From what I understand the capicity of an ArrayList is only increased, to decrease it must copy one array to another.
据我了解,ArrayList 的容量只会增加,要减少它必须将一个数组复制到另一个数组。
I have tried my own experiment to answer you question. You can't lookup the current capacity of an array list so I am running the garbage collector and checking free memory.
我已经尝试过自己的实验来回答您的问题。您无法查找数组列表的当前容量,因此我正在运行垃圾收集器并检查可用内存。
My results are:
Before: 125637904
After Aloc: 126959888 -1321984
After Insert: 126718560 241328
After Clear: 126958496 -239936
After trim: 126998432 -39936
After nullify: 126998400 32
Which is weird and I can't explain. Allocating the list reduced free memory. Inserting into the list increased free memory (I didn't expect that) Clearing the list reduced free memory (???) trimming the list decreases free memory again (doesn't seem to clear it) and setting the list pointer to null should get us back to where we started but it doesn't!
这很奇怪,我无法解释。分配列表减少了可用内存。插入列表增加了可用内存(我没想到)清除列表减少了可用内存(???)修剪列表再次减少了可用内存(似乎没有清除它)并将列表指针设置为 null 应该让我们回到我们开始的地方,但它没有!
My code is below:
我的代码如下:
package metcarob.com.dev.rubbish;
import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
private static long outputMem(String pre, long last) {
Runtime.getRuntime().gc();
String pre2 = " " + pre;
System.out.print(pre2.substring(pre2.length()-20) + " ");
long tv = Runtime.getRuntime().freeMemory();
System.out.print(tv);
if (last!=0) {
System.out.print(" " + (last - tv));
}
System.out.println("");
return tv;
}
public static void main(String[] args) {
long lm = outputMem("Before:",0);
ArrayList<String> lis = new ArrayList<String>();
lis.ensureCapacity(10000);
lm = outputMem("After Aloc:", lm);
for (int c=0;c<10000;c++) {
lis.add(new String("ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"));
};
lm = outputMem("After Insert:", lm);
lis.clear();
lm = outputMem("After Clear:", lm);
lis.trimToSize();
lm = outputMem("After trim:", lm);
lis = null;
lm = outputMem("After nullify:", lm);
}
}
回答by David V
You asked about performance implications. You have to clarify what you mean by "decreasing" performance. If you had to resize the array every time that you decreased the array, you would end up re-copying the array each time. On the other hand, if the capacity remains the same, then you are taking up unneeded memory.
您询问了性能影响。您必须澄清“降低”性能的含义。如果每次减少数组时都必须调整数组大小,那么每次最终都会重新复制数组。另一方面,如果容量保持不变,那么您正在占用不需要的内存。
It is your use-case which determines how this impacts the performance perceived by the user. Are they running on a machine with low memory? Are we talking about large, mostly static arrays? Is the array changing all the time?
您的用例决定了这如何影响用户感知的性能。它们是否在内存不足的机器上运行?我们在谈论大型的,主要是静态数组吗?数组是否一直在变化?
The Java implementation only changes the underlying array if it needs to. This favors avoiding unnecessary copies at the expense of memory size. But, they give you ability to trim it if necessary.
Java 实现仅在需要时更改底层数组。这有利于以牺牲内存大小为代价避免不必要的副本。但是,它们可以让您在必要时修剪它。