Java 在实例化时定义Arraylist的大小有什么好处吗

Java 在实例化时定义Arraylist的大小有什么好处吗,java,arrays,collections,arraylist,Java,Arrays,Collections,Arraylist,在实例化时定义Arraylist的大小有什么好处吗 请纠正我,如果我错了,或者如果这是一个重复的可能的其他问题。我找了,但找不到我要找的东西 定义Arraylist的初始容量是否有好处。我想默认是10 在调整Arraylist的大小时,如果我们在实例化时声明,它会有所帮助。另外,如何潜在地克服内部调整Arraylist大小的开销?如果您知道所需的容量,预先提供它可以提高性能。否则,在添加元素时,列表实现可能需要将内部数组复制到更大的数组中,可能需要重复执行。ArrayList在内部使用数组,因此

在实例化时定义Arraylist的大小有什么好处吗

请纠正我,如果我错了,或者如果这是一个重复的可能的其他问题。我找了,但找不到我要找的东西

定义Arraylist的初始容量是否有好处。我想默认是10


在调整Arraylist的大小时,如果我们在实例化时声明,它会有所帮助。另外,如何潜在地克服内部调整Arraylist大小的开销?

如果您知道所需的容量,预先提供它可以提高性能。否则,在添加元素时,列表实现可能需要将内部数组复制到更大的数组中,可能需要重复执行。

ArrayList在内部使用数组,因此当ArrayList需要额外容量时,它必须在内部创建一个新数组,并将元素复制到新数组中


通过预先估计或查找ArrayList的确切大小,可以克服调整ArrayList大小的开销。或者,您可以确保ArrayList永远不会超过指定的大小,方法是处理业务逻辑,然后在ArrayList达到所需的最大大小时删除元素。最后,您可以使用一种不同的数据结构,在内部不使用阵列,以完全避免增长问题。

ArrayList
指定初始容量可以并将在正确使用的情况下提高性能。如果使用错误,可能会影响性能

例如,如果您正在循环中创建新的
ArrayList
实例,并且知道如何计算实际的最终大小或合理的起始大小,那么这样做是值得的

但通常情况下,它要么不值得,要么甚至有害:

  • 如果“防御”分配过多,内存使用和初始化成本可能会超过使用默认大小调整大小的成本
  • 如果代码不断发展,理想列表大小发生变化,但您忘记了调整自定义初始容量,那么优化可能会变得悲观
  • 你花在微观优化上的时间通常最好花在其他事情上
  • 每个附加元素的平均成本是恒定的:由于大小加倍,列表中的每个元素平均只移动了一次(调整大小之前)或两次(调整大小之后)。通常,处理放入列表的对象的成本要高出许多倍,因此调整大小的总体影响无关紧要

对于可索引数组是一个很好的选择的应用,
ArrayList
基本上与它得到的一样好

LinkedList
尤其在某些情况下似乎更好,但事实并非如此!它有更大的内存开销(每个列表项都有额外的分配!),因此,即使在它被认为是有效的情况下,平均性能也会更差,甚至在Java中,LinkedList最后的插入也不能保证是O(1),因为GC可能会在分配时启动。它只适用于非常特殊的情况,例如一些并发算法

一个优化有时是可能的:如果您有装箱的原始类型的<代码> ARARYLIST/<代码(如<代码> ARAYLIST/<代码>),考虑使用原始类型数组(如<代码> INT[] < /代码>)。这实际上并没有解决调整大小的问题,但它避免了装箱实例的开销。但这只适用于基本类型,而不是例如

Strings

如果你能忍受一些额外的限制,你也可以创建自定义的
列表
。例如,如果您愿意增加访问时间(从直接索引访问到一次额外的查找),并且只需要在末尾插入或删除,则可以创建一个自定义的
列表
实现,它是普通数组的内部
ArrayList
。因此,当您插入一个内部数组时,您将创建一个新数组并插入其中,而不是重新分配旧数组。但由于两级结构的开销,这很少是一个整体改进,更现实地说,这是使用
LinkedList
的替代方案(同样,这也是非常罕见的正确选择)

所以一般来说,若调整数组列表的大小是个问题,最好的解决方法就是使用更强大的计算机。另一个解决方案是改进整体算法,或者总体上提高性能(因为总体性能才是关键,而不是一些小细节的孤立性能)


有趣的是,这实际上是如何从“旧时代”的计算改变而来的。对于交互式应用程序,您希望某些操作在真实世界的时间限制内发生,这样用户体验就不会受到影响。对于较慢的计算机,数组列表大小调整在相当小的列表大小下会非常耗时

但是CPU和内存性能的提高速度比典型的列表项计数要快,所以类似于一次性调整百万元素列表的大小是没有问题的:当内存访问速度以每秒千兆字节为单位时,它只移动了4/8兆字节


此外,多线程已经变得越来越普遍,非交互线程的最坏情况响应时间其实并不重要,它更多的是关于总体吞吐量,只要UI线程保持快速。因此,如果您正在处理这样的大数据,通常最好将数据处理移到别处(另一个线程,一个真实的数据库),而不是尝试在UI线程中优化列表操作。

通过Javadoc扫描它,Arraylist的用法我们是否应该总是忽略内部大小调整的问题,或者是否有任何可能的方法来处理它?@Suraj在几乎所有情况下,您都应该忽略它。如果您有一个担心内存不足的用例,那么您可能需要使用不同的数据结构。类似地,如果您有一个用例,调整大小数组的内部数组的时间成本可能是昂贵的,那么您也需要考虑其他数据结构。