2

I have this:

String[][] numbers = {
     {"one", "two", "three"},
     {"four", "five", "six"},
     {"seven", "eight", "nine"}
}

String[][] tmp;

What i what now is that i clone numbers into tmp but LIMITED to 2 arguments per row. I don't wanna initialize any size

Output of tmp:

{      
    {"one", "two"},         
    {"four", "five"},         
    {"seven", "eight"}
}

What i tried:

String[][] cloneArray(String[][] elements) {
    int length = elements.length;
    String[][] target = new String[length][2];
    for (int i = 0; i < length; i++) {
        System.arraycopy(elements[i], 0, target[i], 0, elements[i].length);
    }

    return target;
}

I can't give a particular size becouse i have a function that updates(adds) the array:

String[][] append(String[][] arr, String[] element) {
    final int N = arr.length;
    arr = Arrays.copyOf(arr, N + 1);
    arr[N] = element;
    return arr;
}

I get java.lang.ArrayIndexOutOfBoundsException

UkFLSUI
  • 5,509
  • 6
  • 32
  • 47

2 Answers2

3

We can filter out the inner array beyond the second element, by getting a Stream<String[]> out of it and applying the Stream#map on it so that the size of the new inner array is limited to 2 elements:

String[][] numbers = {
                       {"one", "two", "three"},
                       {"four", "five", "six"},
                       {"seven", "eight", "nine"}
                     };
String[][] tmp = Arrays.stream(numbers)
                        .map(arr -> (arr != null && arr.length > 2)
                                         ? Arrays.copyOf(arr, 2) 
                                         : arr)
                       .toArray(String[][]::new);
System.out.println(Arrays.deepToString(tmp));

Output:

 [[one, two], [four, five], [seven, eight]]
Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44
1

You are using wrong syntax for System.arraycopy(). The declaration of the method is like this:

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

Where, src and dest are source array and destination array respectively. The arraycopy function itself handles the position from srcPos to srcPos + length and copy it from destPos to destPos + length. So, no need to loop through the elements and use arraycopy() for each of them.

So, for your code, the fix will be:

String[][] cloneArray(String[][] elements) {
    int length = elements.length;
    String[][] target = new String[length][2];
    System.arraycopy(elements, 0, target, 0, elements.length);
    return target;
}

And if you don't want to use arraycopy rather want to loop through the elements and manually copy elements, you can also do that simply:

String[][] cloneArray(String[][] elements) {
    int length = elements.length;
    String[][] target = new String[length][2];
    for (int i = 0; i < length; i++) {
        for (int j = 0; j < 2; j++) {
            target[i][j] = elements[i][j];
        }
    }
    return target;
}
UkFLSUI
  • 5,509
  • 6
  • 32
  • 47