我将以下3D数组设置为两个程序状态之间的缓冲区。
private boolean state [][][] = new boolean [20][20][2];
我正在尝试复制
中的所有内容state[0-19][0-19][1]
到
state[0-19][0-19][0]
目前我正在使用for循环,这很好,但我不禁觉得有更好的方法。我知道我可以使用两个单独的2D数组并做一个简单的复制,但我很想知道是否有任何解决方法。
当前循环:
for (int i=0;i<20;i++){
for (int j=0;j<20;j++){
state[i][j][0]=state[i][j][1];
}
}
答案 0 :(得分:2)
有时您可以用System.arraycopy
替换内部循环,这样会更快。但是不相信你的记忆布局。
如果可能,请考虑更新引用,而不是复制数组。回想一下,java中的“多维”数组实际上是数组的数组。
特别是
boolean[] tmp = multi[0];
multi[0] = multi[1];
multi[1] = tmp;
以接近零的成本交换两个数组引用。这比复制快很多,然后覆盖旧值。但有时你需要一个副本(如果你没有覆盖旧值),那么你就不能这样做。
请注意,你不应该盲目地这样做:
multi[0][0] = 1;
multi[1] = multi[0];
multi[1][0] = 0;
System.err.println(multi[0][0]);
将打印0
,因为现在multi[0]
和multi[1]
指向相同的嵌套数组,您应该使用它。
multi[1] = multi[0].clone();
请注意,克隆也不是深,因此multi.clone()
将指向与multi
相同的嵌套数组。在Java中没有内置的深度克隆或深度数组,你需要使用循环。
但是,如果你想将第二个元素复制到许多数组中的第一个元素,那么这些都不会起作用。这是你的内存布局问题。
回想一下你的数据结构在内存中的样子:
boolean[][][] -> boolean[][] -> boolean[]{ 0, 1 }
\ \> boolean[]{ 0, 1 }
\> boolean[][] -> boolean[]{ 0, 1 }
\> boolean[]{ 0, 1 }
您希望在每个数组中复制一个元素。它们可以整个内存(每个boolean[]...
都是它自己的对象!),所以没有办法加快原语的速度 - 数据是分散的。如果可能的话,也许考虑更改内存布局。
还要考虑布尔数组的替代方案。布尔值占用1个字节的内存,但只存储一位(请注意,这可能会更快,因此本身也不错!)。但有时将整个布尔数组存储在BitSet
或long
中,然后使用实际的位操作是有意义的。但是获得,有时它确实付出了代价,有时它会受到伤害。
答案 1 :(得分:0)
我喜欢nhahtdh重新组织维度的解决方案,但请注意,如果您复制引用,那么如果您稍后更改state[0]
,state[1]
将反映更改,反之亦然(请注意, ,实际上可能是你想要的)。该引用可以在2个地方访问,但只在一个地方存储内容 - 旧指针/参考混淆。单元测试是你的朋友:-)
如果你有一个单个维数组,Arrays.copyOf()
方法可以帮助避免一些循环代码。但请记住,某些sometype[]
对象的副本会将引用复制到该对象,而不是所有单个sometype
对象。
当然,您可以开始使用.clone()
甚至序列化来获取sometype[]
对象的“深层”副本,但这会比您的嵌套循环快得多。