删除元素时,ArrayList的容量是否会减少?

ArrayList的默认容量为10个对象。 当大小超过10个对象时,ArrayList将在内部增加其容量。 当我们从ArrayList中删除对象时,容量是否会降低。

如果ArrayList容量没有减少,这是否会导致性能问题?

它不会自动降低这一点。 从文档。

  public void trimToSize() 

将此ArrayList实例的容量调整为列表的当前大小。 应用程序可以使用此操作来最小化ArrayList实例的存储。

在arraylist中有几个remove方法,我将使用remove by index version作为这个例子

  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; } 

最重要的是要注意,在elementData永远不会创建新数组,因此它的大小不会改变,只会复制元素。

如果你需要减少数组列表的容量(你通常不会),请使用trimToSize()

ArrayList提供了一个方法trimToSize(),它“将此ArrayList实例的容量调整为列表的当前大小。应用程序可以使用此操作来最小化ArrayList实例的存储。” 请参阅http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#trimToSize() 。

如果任何其他方法默默地执行此类操作,那将取决于JRE提供的实现。

根据我的理解,只增加了ArrayList的容量,减少它必须将一个数组复制到另一个数组。

我已经尝试过自己的实验来回答你的问题。 您无法查找arrays列表的当前容量,因此我正在运行垃圾收集器并检查可用内存。

 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 

这很奇怪,我无法解释。 分配列表减少了可用内存。 插入列表增加了可用内存(我没想到)清除列表减少了可用内存(???)修剪列表再次减少可用内存(似乎没有清除它)并将列表指针设置为null应该让我们回到我们开始的地方,但事实并非如此!

我的代码如下:

 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 lis = new ArrayList(); 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); } } 

您询问了性能影响。 你必须通过“降低”表现来澄清你的意思。 如果每次减少数组时都必须调整数组大小,则每次都会重新复制数组。 另一方面,如果容量保持不变,那么您将占用不需要的内存。

这是您的用例,它决定了它如何影响用户感知的性能。 它们是在内存不足的机器上运行吗? 我们在讨论大型静态数组吗? arrays是否一直在变化?

Java实现仅在需要时才更改底层数组。 这有利于以内存大小为代价避免不必要的拷贝。 但是,如果有必要,它们可以让你修剪它。

do the the capacity decrease when we remove the object from ArrayList.

答案很简单。如果您观察到ArrayList类的源代码,您将得到答案。
没有操作来减少ArrayList的remove()方法的容量。