4

After finding out the hard way that clone() does not work as intended for multidimensional arrays, now I write

for(int k = 0; k < Nz; k++){
    for(int j = 0; j < Ny; j++){
        for(int i = 0; i < Nx; i++){
            grid_copy[i][j][k] = grid[i][j][k];
        }
    }
}           

for every array. This feels so depressingly low level and anti DRY. Could anyone suggest a more general way of doing this?

  • possible duplicate of [Deep cloning multidimensional arrays in Java...?](http://stackoverflow.com/questions/200387/deep-cloning-multidimensional-arrays-in-java) – Brian Roach Feb 21 '12 at 22:10

3 Answers3

2

This official tutorial explains how to use the arraycopy method to efficiently copy data from one array into another. I think it works only for one-dimensional arrays, but you can use it to copy the various "blocks of one-dimensional array" contained within your three-dimensional grid. You may find it useful!

enzom83
  • 8,080
  • 10
  • 68
  • 114
  • Thanks. That should be the fastest method, but in no way elegant.. Before asking the question I already found a nice comparison of standard methods ( http://www.javapractices.com/topic/TopicAction.do?Id=3 ). I'm still hoping someone might know something less low level. – Ivan Lappo-Danilevski Feb 21 '12 at 22:32
2

If you really really want a generic copier, I just whipped this up here and did some basic testing. It's interesting but I don't think it's any better because what you gain in flexibility is lost in readability.

private void copy(Object source, Object dest) {
    if(source.getClass().isArray() && dest.getClass().isArray()) {
        for(int i=0;i<Array.getLength(source); i++) {
            if(Array.get(source, i) != null && Array.get(source, i).getClass().isArray()) {
                copy(Array.get(source, i), Array.get(dest, i));
            } else {
                Array.set(dest, i, Array.get(source, i));
            }
        }
    }
}
deraj
  • 91
  • 2
  • This is the only general way to do it. (And yeah, it's ugly.) You're not going to find a better way. – Louis Wasserman Feb 21 '12 at 22:41
  • This is definitely a solution! But unfortunately it's rather slow (maybe due to being recursive). In my application, I have measured it to be more than two times slower than the hard coded version. – Ivan Lappo-Danilevski Feb 21 '12 at 23:03
  • @LouisWasserman Only general way? What about returning a copy that was constructed completely independently like this: http://stackoverflow.com/a/16256146/1493294 Sometimes you care more about not being made to think than about speed. – candied_orange Jan 07 '15 at 11:39
  • That approach seems equivalent except for creating a new output array, which I deliberately didn't do because the OP's question didn't ask for it. – Louis Wasserman Jan 07 '15 at 16:07
0

I am not aware of a more general way of doing this. I would simply define a function to do it.

  public void copyMultidimensionalArray(int[][][] destination,int[][][] source)
    {
        // your above code here   
    }

And then I would simply call that function each time.

 copyMultidimensionalArray(grid_copy,grid);

Can't get more elegant than that, can I?

Note that the above example is only using integer arrays. You could of course make it more generic using arrays of type Object.

CodeBlue
  • 14,631
  • 33
  • 94
  • 132
  • Thanks. I'll try that, but more elegant would be not to specify the three dimensions at all and use it for any dimension. – Ivan Lappo-Danilevski Feb 21 '12 at 22:17
  • Yes, but I think for all practical purposes, multidimensional usually goes up to 3 dimensions. So you could hardcode it for a two dimensional copy and a three dimensional copy. – CodeBlue Feb 21 '12 at 22:24