在实例化时是否有定义Arraylist大小的优势。?
如果错误或与其他可能的问题重复,请纠正我。我搜查了但是找不到我要找的东西。
定义Arraylist的初始容量是否有优势?它的默认值为10。我猜。
在调整Arraylist的大小时,如果我们在实例化时声明它会有所帮助。另外,如何潜在地克服内部调整Arraylist大小的开销。?
答案 0 :(得分:5)
ArrayLists在内部使用数组,因此当ArrayList需要额外容量时,它必须在内部创建一个新数组并将元素复制到新数组。
您可以通过预先估计或查找ArrayList的确切大小来克服调整ArrayList大小的开销。或者,您可以通过处理业务逻辑确保ArrayList永远不会超出指定的大小,然后在ArrayList达到其最大所需大小时删除元素。最后,您可以使用不在内部使用数组的不同数据结构来完全避免增长问题。
答案 1 :(得分:4)
如果您知道所需的容量,提前提供它可以提高性能。否则,在添加元素时,列表实现可能需要将内部数组复制到较大的数组 - 可能重复。
答案 2 :(得分:2)
指定ArrayList
的初始容量可以并且如果正确使用将提高性能。如果用得不对,可能会影响性能。
例如,如果要在循环中创建新的ArrayList
实例并且知道如何计算实际最终大小或合理的起始大小,那么值得做。
但通常它不值得,甚至有害:
对于可索引数组是一个不错的选择的用途,ArrayList
基本上和它一样好。
LinkedList
尤其可能似乎更好,但事实并非如此!它有更大的内存开销(每个列表项额外分配!),因此即使对于它被认为有效的情况,平均性能也会更差,甚至在最终的LinkedList插入也不能保证在Java中的O(1),因为GC可能会踢在分配。它非常适合非常特殊的情况,例如一些并发算法。
有时可能进行一次优化:如果您有ArrayList
盒装基元类型(如ArrayList<Integer>
),请考虑使用基本类型数组(如int[]
)。这实际上并没有克服调整大小问题,但它避免了盒装实例的开销。但这仅适用于原始类型,而不适用于Strings
。
如果你可以利用一些额外的限制,你也可以创建自定义List
。例如,如果您愿意增加访问时间(从直接索引访问到一次额外查找)并且只需要在末尾插入或删除,则可以创建内部{{1}的自定义List
实现普通数组。因此,当您插入并填充内部数组时,您将创建一个新数组并插入其中,而不是重新分配旧数组。但由于两级结构的开销,这很少是一个整体改进,并且更实际上可以替代使用ArrayList
(这也是很少正确的选择)。
所以一般情况下,如果LinkedList
调整大小是有问题的,那么的最佳方法是为了获得更强大的计算机;)。另一个解决方案是改进整体算法,或者通常改善性能(因为总体性能是重要的,而不是一些小细节的孤立性能)。
有趣的是,这实际上是如何从计算的“旧时代”改变的。使用交互式应用程序,您希望某些操作在某个现实世界的时间限制内发生,因此用户体验不会受到影响。对于速度较慢的计算机,在列表大小非常小的情况下,数组列表调整大小会非常耗时。
但CPU和内存性能比典型的列表项计数提高得更快,所以像一次性调整百万元素列表的大小是没有问题的:当内存访问速度以千兆字节/秒为单位时,它只移动4/8兆字节
此外,多线程已经变得越来越普遍,非交互式线程的最坏情况响应时间并不重要,只要UI线程保持活泼,它就更多地关注整体吞吐量。因此,如果您正在处理大型数据,那么将数据处理移动到其他地方(另一个线程,一个真正的数据库)通常比尝试优化UI线程中的列表操作更好。