toobee
toobee

Reputation: 2752

Java System.arraycopy resizes destination to source size?

Hi I am trying to use System.arraycopy to copy a smaller array to a bigger one. This does work, but the destination is auto-resized to the source dimension.

I have to copy together a table for printing data. I want to copy 3 columns from table A into table C and than in a second step table B's 4th column als 4th column in C. The number of rows are in all cases the same. This idea fails because array copy seems to enforce the source dimensionality on the destination. This is kind of unexpected.

I do not want to iterate as this will take a long time if I use production-size data (>1 million or more rows)). I thought arracopy would be nice and fast solution.... any work arounds?

  public class Test {

    public static void main(String[] args) {
        Integer[][] s = new Integer[2][2];

        Integer[][] d = new Integer[3][3];

        System.out.println(d.length + " " + d[0].length);

        System.arraycopy(s, 0, d, 0, 2);

        System.out.println(d.length + " " + d[0].length);
    }

}

This is how I call the API, anything wrong or is this resize avoidable?

Upvotes: 0

Views: 1191

Answers (2)

Stephen C
Stephen C

Reputation: 719229

The arraycopy method definitely does not change the size of its argument arrays.

What is going on here is that you misunderstand how (supposedly) multi-dimensional arrays work in Java.

The reality is that Java arrays are essentially one dimensional. For instance, a String[][] is actually an array of arrays of Strings. When you use arraycopy to copy from one String[][] to another, you are not copying the references to the Strings. Rather you are actually performing a shallow copy of the references to the String[] objects. In your case, that is changing the number of columns ... according to your mental model of the array.

Remember, the arraycopy method simply does a shallow copy of the top level array. It is simply treating the String[][] as an array of String[] objects ... and copying their references from the source array to the destination array.

If you want to keep the number of columns the same, the simplest way is to copy the elements with nested for loops. I expect that if you profiled the code, you would find that the time you are saving with your use of arraycopy is small compared with the overheads of 1) performing the database query, 2) transferring the data through the resultset, and 3) copying it into a List, and 4) the toArray(...) call.

Here is the javadoc for the arraycopy method. Note that there is no mention of resizing.

Upvotes: 1

Kayaman
Kayaman

Reputation: 73568

Your "resizing" comes from the fact that you're copying 2D arrays. Nothing is resized, it's overwritten.

s[0] = new Integer[2];
// Arraycopy copies s[0] to d[0]
d[0] = s[0];  // Therefore d[0] = new Integer[2];

You'll have to iterate the outer array and perform the arraycopy for each of the 2nd level arrays to avoid this "resizing".

Upvotes: 1

Related Questions