我正在制作一个Java程序,其中一个球在屏幕上反弹。用户可以添加其他球,它们都互相反弹。我的问题在于存放添加的球。目前,我正在使用ArrayList来存储它们,每次按下空格键时,都会创建一个新的球类并将其添加到数组列表中。这是最有效的做事方式吗?我没有在开始时指定数组列表的大小,因此每次用户想要一个新球时,必须在数组上分配一个新空间是低效的,即使球数会增加数百?还有另一个我可以用来以更有效的方式处理这个问题的课程吗?
谢谢!
修改
对不起,我应该更清楚了。我每30毫秒迭代一次球,使用嵌套的for循环来查看它们是否相互交叉。我最常访问一个球(用户可以用箭头键控制的球,游戏的另一个特征),但用户可以选择切换控制球。球永远不会被移除。所以,我经常在球上执行一些相当复杂的计算(我使用自己的矢量类将它们彼此移开)。
答案 0 :(得分:5)
测量并找出答案!一目了然,获得这些问题答案的最佳方法通常是设置基准并交换不同的集合类型。
我可以告诉你,它不会在你向ArrayList添加新项目的每个时间分配新空间。分配了额外的空间,以便有增长的空间。
LinkedList是另一个List选项。添加项目非常便宜,但随机访问(list.get(10))很昂贵。如果您不需要有序访问(尽管也有有序集),集合也可以是好的,如果您通过某种键/ id访问它们,则需要Map实现。这完全取决于你如何使用该系列。
根据添加的详细信息进行更新 听起来你大部分都是在整个列表中进行顺序读取。在那种情况下,LinkedList可能是您的最佳选择。尽管如此,如果你只将List接口公开给你的其余代码(甚至更普通的Collection),你可以轻松地交换不同的实现并实际测量差异。
答案 1 :(得分:4)
关于Java中的ArrayList
,最后删除并添加一个元素的复杂性为Amortize O(1)
。或者,你可以说,它在大多数情况下几乎都是有效的。 (在极少数情况下,它会很糟糕。)
但在选择数据结构之前,您应该更仔细地考虑您的设计。
您的收藏中经常有多少个对象。如果它很小,您可以自由选择您觉得易于使用的任何数据结构。它几乎不会丢失您的代码的性能。
如果您经常在所有球中找到一个球,则HashMap
或HashSet
等其他数据结构会更好。
或者您经常在列表中间删除,也许LinkedList
可能是合适的选择:)
答案 2 :(得分:4)
ArrayList
是一个高度优化且非常高效的包装器,位于普通Java数组之上。复制数组元素的时间开销很小,当分配的大小小于所需的元素数时会发生这种情况。当您将阵列增加到几百个项目时,复制将发生不到十次,因此您提前支付的价格非常小。您可以通过建议ArrayList
的初始大小来进一步降低开销。
从ArrayList
的中间删除确实需要线性时间。如果您打算经常删除项目和/或将它们插入列表中间,这可能会成为一个问题。但请注意,开销不会比普通数组的开销差。
我每30毫秒迭代一次球,使用嵌套的for循环来查看它们是否相互交叉。
这与存放球的集合没有多大关系。您可以使用spatial index来提高查找十字路口的速度。
答案 3 :(得分:3)
我建议你找出你需要访问球的方式,并选择一个合适的接口(不实现),例如。如果您只是按顺序访问,请使用列表。如果您需要通过ID查找球,请考虑一张地图。界面应该在功能方面符合您的要求,而不是速度/效率。
然后选择一个实现,例如。 HashMap或TreeMap,并编写代码。
之后,对其进行分析 - 您的代码在球访问代码中是否效率低下?如果是这样,那么尝试通过切换到更符合您需求的替代实现进行优化。