4

我将以下 3D 数组设置为两个程序状态之间的缓冲区。

private boolean state [][][] = new boolean [20][20][2];

我正在尝试复制所有内容

state[0-19][0-19][1]

state[0-19][0-19][0]

目前我正在使用 for 循环,效果很好,但我不禁觉得有更好的方法。我知道我可以只使用两个单独的二维数组并做一个简单的复制,但我有兴趣看看是否有任何解决方法。

电流回路:

for (int i=0;i<20;i++){
        for (int j=0;j<20;j++){
            state[i][j][0]=state[i][j][1];
    }
}
4

2 回答 2

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]);

将 print 0,因为 nowmulti[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但有时将整个布尔数组存储在 a或 along中,然后使用实际的位操作是有意义的。但是收获,有时它确实付出了代价,有时它会受到伤害。

于 2013-02-27T10:26:01.323 回答
0

我喜欢 nhahtdh 的重新组织维度的解决方案,但请注意,如果您复制参考,那么如果您稍后更改state[0]state[1]将反映更改,反之亦然(请注意,这实际上可能是您想要的)。引用可以在 2 个地方访问,但只能在一个地方存储内容 - 旧的指针/引用混淆。单元测试是你的朋友:-)

如果您有一个维数组,该Arrays.copyOf()方法可以帮助避免一些循环代码。但请记住,某个sometype[]对象的副本将复制对该对象的引用,而不是所有单个sometype对象。

您当然可以开始使用.clone()甚至序列化来获取sometype[]对象的“深层”副本,但是这会比嵌套循环更快地复杂。

于 2013-02-27T10:39:44.000 回答