Copying only the first two dimensions of a 3D array

I have the following three-dimensional array configured as a buffer between two program states.

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

I'm trying to copy all of

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

to

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

Right now I'm using a for loop, which works great, but I can't help but feel that there is a better way. I know that I can just use two separate 2D arrays and make a simple copy, but I'm curious to know if there is a way around this.

Current loop:

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

Sometimes you can replace the inner loop with System.arraycopy , which will be faster. But I do not believe in memory layout.

If possible, instead of copying the array, consider updating the links. Recall that "multidimensional" arrays in java are arrays of arrays.

In particular,

  boolean[] tmp = multi[0]; multi[0] = multi[1]; multi[1] = tmp; 

swaps references to two arrays at a value other than zero. This is much faster than copying and then rewriting old values. But sometimes you need a copy (if you do not overwrite the old values), then you cannot do this.

Please note that you should not do this blindly:

  multi[0][0] = 1; multi[1] = multi[0]; multi[1][0] = 0; System.err.println(multi[0][0]); 

will print 0 because now multi[0] and multi[1] point to the same nested array, and you should have used it.

  multi[1] = multi[0].clone(); 

Note that cloning is also not deep, so multi.clone() will point to the same nested arrays as multi . There is no built-in deep cloning or deep arraycopy in Java, you need to use a loop for this anyway.

But then again, none of them work if you want to copy the second element into the first array of sets. This is the problem of your memory layout.

Recall what your in-memory data structure looks like:

  boolean[][][] -> boolean[][] -> boolean[]{ 0, 1 } \ \> boolean[]{ 0, 1 } \> boolean[][] -> boolean[]{ 0, 1 } \> boolean[]{ 0, 1 } 

you want to copy one element in each array. They can be everywhere in your memory (each boolean[]... is its own object!), So there is no way to speed it up using primitives - the data is scattered. Perhaps consider changing the layout of the memory , if possible.

Also consider alternatives to boolean arrays. Booleans take 1 byte of memory, but only save one bit (note that this can be faster, so it's not so bad!). But sometimes it makes sense instead to store the entire logical array in BitSet or long , and then work with the actual bit operations. But the gain, sometimes it pays, sometimes it hurts.

+2
source

I like the nhahtdh solution to reorganize the measurements, but be careful if you copy the link, then if you later change state[0] , state[1] will reflect this change and vice versa (which, in fact, may be what you want) . The link will be available in 2 places, but will save the content in only one place - the old pointer / link confusion. Unit tests are your friend :-)

If you have a single dimensional array, the Arrays.copyOf() method can help avoid some loop code. But remember that a copy of some sometype[] object copies the reference to the object, not all individual sometype objects.

Of course, you could start playing with .clone() or even Serialization to get "deep" copies of sometype[] , but then it gets harder than your nested loops quickly.

0
source

All Articles