ArrayList的效率

问题描述 投票:1回答:4

我正在用Java创建一个程序,其中一个球在屏幕上反弹。用户可以添加其他球,它们都互相反弹。我的问题在于存放添加的球。目前,我正在使用ArrayList来存储它们,每次按下空格键时,都会创建一个新的球类并将其添加到数组列表中。这是最有效的做事方式吗?我没有在开始时指定数组列表的大小,因此每次用户想要一个新球时,必须在数组上分配一个新空间是低效的,即使球数会增加数百?是否有另一个类我可以用来以更有效的方式处理这个问题?

谢谢!

编辑:

对不起,我应该更清楚了。我每30毫秒迭代一次球,使用嵌套的for循环来查看它们是否相互交叉。我最常访问一个球(用户可以用箭头键控制的球,游戏的另一个特征),但用户可以选择切换控制球。球永远不会被移除。因此,我经常在球上执行一些相当复杂的计算(我使用自己的矢量类将它们彼此移开)。

java performance arraylist
4个回答
5
投票

测量它并找出答案!一目了然,获得这些问题答案的最佳方法通常是设置基准并交换不同的集合类型。

我可以告诉你,每次向ArrayList添加一个新项时,它都不会分配新的空间。分配额外的空间,以便有增长的空间。

LinkedList是另一个List选项。添加项目非常便宜,但随机访问(list.get(10))很昂贵。如果您不需要有序访问(尽管也有有序集),集合也可以是好的,如果您通过某种键/ id访问它们,则需要Map实现。这完全取决于你如何使用该系列。

基于添加的细节进行更新听起来您大多是在整个列表中进行顺序读取。在那种情况下,LinkedList可能是您的最佳选择。尽管如此,如果您只将List接口公开给代码的其余部分(甚至是更常见的Collection),您可以轻松地交换不同的实现并实际测量差异。


4
投票

ArrayList是一个高度优化且非常高效的包装器,位于普通Java阵列之上。复制数组元素的时间开销很小,当分配的大小小于所需的元素数时会发生这种情况。当您将阵列增加到几百个项目时,复制将发生不到十次,因此您提前支付的价格非常小。您可以通过建议ArrayList的初始大小来进一步减少开销。

ArrayList中间删除确实需要线性时间。如果您打算经常删除项目和/或将它们插入列表中间,这可能会成为一个问题。但请注意,开销不会比普通数组的开销差。

我每30毫秒迭代一次球,使用嵌套的for循环来查看它们是否相互交叉。

这与存放球的集合没有多大关系。您可以使用spatial index来提高寻找十字路口的速度。


4
投票

关于Java中的ArrayList,最后删除的复杂性和添加一个元素是Amortize O(1)。或者,你可以说,它在大多数情况下几乎都是有效的。 (在极少数情况下,它会很糟糕。)

但在选择数据结构之前,您应该更仔细地考虑您的设计。

  1. 您的收藏中经常有多少个对象。如果它很小,您可以自由选择您觉得易于使用的任何数据结构。它几乎不会丢失您的代码的性能。
  2. 如果你经常在所有球中找到一个球,那么另一个数据结构如HashMapHashSet会更好。
  3. 或者你经常在列表中间删除,也许LinkedList将是适当的选择:)

3
投票

我建议找出你需要访问球的方式,并选择一个合适的接口(不实现),例如。如果您只是按顺序访问,请使用列表。如果您需要通过ID查找球,请考虑一张地图。界面应该在功能方面符合您的要求,而不是速度/效率方面。

然后选择一个实现,例如。 HashMap或TreeMap,并编写您的代码。

然后,描述它 - 您的代码在球访问代码中是否效率低下?如果是这样,那么尝试通过切换到更适合您需求的替代实现进行优化。

© www.soinside.com 2019 - 2024. All rights reserved.