Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
防止在Java中分配ArrayList迭代器_Java_Android_Iterator_Allocation - Fatal编程技术网

防止在Java中分配ArrayList迭代器

防止在Java中分配ArrayList迭代器,java,android,iterator,allocation,Java,Android,Iterator,Allocation,因此,我在Android上写第一个游戏的过程中,在观看了一个关于游戏优化的冗长演示之后,我一直在检查我的分配情况。当ArrayList为for(Object o:m_ArrayList)约定创建一个隐式迭代器时,我已经设法摆脱了所有游戏中的分配,除了ArrayList中的分配 由于我的所有游戏对象、ai实体等都存储在这些迭代/分配中以便于使用,因此这些迭代/分配的数量相当少 那么我有什么选择呢 理论上,我可以指定合理的上界并使用数组,但我喜欢ArrayList的特性,比如保持代码干净和简单的e

因此,我在Android上写第一个游戏的过程中,在观看了一个关于游戏优化的冗长演示之后,我一直在检查我的分配情况。当ArrayList为for(Object o:m_ArrayList)约定创建一个隐式迭代器时,我已经设法摆脱了所有游戏中的分配,除了ArrayList中的分配

由于我的所有游戏对象、ai实体等都存储在这些迭代/分配中以便于使用,因此这些迭代/分配的数量相当少

那么我有什么选择呢

  • 理论上,我可以指定合理的上界并使用数组,但我喜欢ArrayList的特性,比如保持代码干净和简单的exists和remove

  • 重写ArrayList并提供我自己的迭代器()实现,该实现返回一个类成员,而不是每次使用它时分配一个新的迭代器类型

为了便于使用,我更愿意选择选项2,但我尝试了一下,遇到了一些问题。有人举过我在上面选项2中描述的例子吗?我从泛型类继承时遇到问题,显然类型冲突

第二个问题是,有没有其他选择来避免这些分配

我想作为一个额外的问题,有人知道ArrayList是否预先分配了一定数量的内存插槽(在ctor中指定或作为某个可移动值指定),并且只要您保持在这些范围内,就永远不需要进行任何其他分配吗?即使在清除()之后


提前感谢,很抱歉有这么多信息,但我认为这些信息可能对很多人有用。

使用位置迭代

for ( int i = 0, n = arrayList.size( ); i < n; ++i )
{
   Object val = arrayList.get( i );
}
或者在运行时

arrayList.ensureCapacity( numSlots );

对于奖金->

我首先回答奖金问题:是的,
ArrayList
会预先分配插槽。它有一个将所需插槽数作为参数的构造函数,例如
newarraylist(1000)
<代码>清除不会释放任何插槽

返回共享迭代器引用有一些问题。主要问题是您无法知道迭代器何时应该重置为第一个元素。考虑下面的代码:

CustomArrayList<Whatever> list = ...
for (Whatever item : list) {
    doSomething();
}
for (Whatever item : list) {
    doSomethingElse();
}
在这种情况下,您不希望在调用之间重置迭代器

@Alexander Progrebnyak的答案可能是在不使用
迭代器的情况下迭代列表的最佳方式;只需确保您具有快速随机访问权限(即永远不要使用
LinkedList


我还想指出的是,您正在进行一些非常繁重的微优化。我建议您在投入大量时间之前对代码进行分析,并找出分配迭代器是否是一个真正的问题。即使是在游戏中,你也应该只优化需要优化的内容,否则你可能会花很多很多天的时间从一分钟长的操作中减少几毫秒。

谢谢,我确实考虑过这种方法,事实上我曾经使用过类似的方法,但在做了一点研究后被推迟了。与迭代器相比,get(i)函数的迭代速度似乎较慢。我想,这是因为节省了分配。。。。可能不得不experiment@makar. 实际上,对于
ArrayLists
get
将与使用迭代器一样快或更快。它直接引用底层数组的位置元素。在Java5之前没有这样做。迭代器在java中已经存在了很长一段时间。这很有趣,我会尝试找到任何让我不这么想的东西,如果我真的这么想的话。也许我在想其他的收藏品。@jtahlborn。你说得对!在Java5之前,迭代器就已经存在了,但是(
for(objectobj:collection)
loop没有。我没有看到任何关于测试/评测的提及。这实际上是一个性能瓶颈吗?根据您的额外问题,没有初始容量参数的ArrayList构造最初会为列表中的10个对象分配空间,并在需要时按初始容量增长。您可以调用
trimToSize
以节省空间。对于奖金问题,ArrayList默认分配10个容量@托马斯。潜在的,潜在的不是,在低规格的手机上偶尔会有暂停,我只能将其归因于GC,但无法100%确认。但是我想如果我可以用ArrayList替代其他类型的,那么这将是一个快速的胜利,没有任何负面影响。谢谢你的详细回答。我知道返回单个实例迭代器的相关风险,但如果这意味着停止分配,我很乐意遵守所需的规则。至于你们的另一点,我一直都很小心,不要在游戏中进行任何迭代,所以看到所有这些隐式分配都被吐出来有点令人沮丧!我抵制了过早进行大量优化的冲动,但我觉得如果我可以将ArrayList换成另一种类型,那么这将是一个快速修复,不会影响其他任何事情。但我明白了*不做任何分配。不是迭代。
CustomArrayList<Whatever> list = ...
for (Whatever item : list) {
    doSomething();
}
for (Whatever item : list) {
    doSomethingElse();
}
for (Whatever first : list) {
    for (Whatever second : list) {
        ...
    }
}