只复制3D数组的前2个维度



我将下面的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];
    }
}

有时您可以用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字节的内存,但只存储1位(注意,这样可以更快,所以它本身并不坏!)。但有时将整个布尔数组存储在BitSetlong中是有意义的,然后再进行实际的位操作。但收获,有时是值得的,有时是痛苦的。

我喜欢nhahtdh重新组织维度的解决方案,但要注意,如果复制引用,那么如果稍后更改state[0], state[1]将反映更改,反之亦然(请注意,这实际上可能是您想要的)。引用可以在两个地方访问,但只在一个地方存储内容——旧指针/引用混淆。单元测试是你的朋友:-)如果你有一个维数组,Arrays.copyOf()方法可以帮助你避免一些循环代码。但是请记住,某些sometype[]对象的副本将把引用复制到该对象,而不是所有单独的sometype对象。

你当然可以开始使用.clone()或甚至序列化来获得sometype[]对象的"深度"副本,但这很快就会比嵌套循环更复杂。

相关内容

  • 没有找到相关文章

最新更新