0

I need to reset the size of an array from w[i][j][q][k] to w[i+2][j+2][q][k]. I don't want to use an array of lists as I would have to change large parts of my program. I read in some threads that it is possible to create a new array of the desired size, and copy the contents from the original array to the new array using java.lang.System.arraycopy(...).

I tried this as follows, but it does not work with my approach:

 int [][][][] w = new int [18][18][[Main.V+1][Main.k]; 

 (...)

 int[][][][] wNew = new int[20][20][Main.V+1][Main.k]; 

 for(int i=0; i<wNew.length; i++){
        for(int j=0; j<wNew[0].length; j++){
            for(int q=0; q<wNew[0][0].length; q++){
                for(int k=0; k<wNew[0][0][0].length; k++){
                    System.arraycopy(w, 0, wNew, 0, 18);
                }
            }
        }
    }

w = wNew;

(...)

when manipulating the array at the added positions, a java.lang.ArrayIndexOutOfBoundsException: 18 occurs (example below:

w[0][19][1][0] = 1; (this line now causes an error)
2
  • 2
    How does it not work with your approach? Commented Jan 10, 2017 at 2:12
  • I added the error message. Commented Jan 10, 2017 at 2:24

1 Answer 1

1

System.arraycopy(w, 0, wNew, 0, 20);

this 20 is the number of array element to copy. You've put the new size, use the old one. In your example it's 18.

Secondly your for loops are based on your new size. This is backward, you have to read your original array and insert into the new array, so you have to iterate on the original array size(for resizing up, of course to make it smaller it would be the other way around).

But more importantly you don't have to iterate on all the dimentions. I'll past you some code you'll can execute to see for yourself.

import java.util.Arrays; import java.util.Random;

public class Test {

    public static final int SIZE_DIM1 = 2;
    public static final int SIZE_DIM2 = 2;
    public static final int SIZE_DIM3 = 5;
    public static final int SIZE_DIM4 = 5;
    private static final int INCREMENT = 2;

    public static void main(String[] args) {
        int[][][][] w = new int[SIZE_DIM1][SIZE_DIM2][SIZE_DIM3][SIZE_DIM4];

        randomFill(w);

        display(w);

        int[][][][] wNew = new int[SIZE_DIM1 + INCREMENT][SIZE_DIM2 + INCREMENT][SIZE_DIM3][SIZE_DIM4];

        for (int i = 0; i < w.length; i++) {
            for (int j = 0; j < w[i].length; j++) {
                System.arraycopy(w[i][j], 0, wNew[i][j], 0, w[i][j].length);
            }
        }

        display(wNew);

        w = wNew;

        w[0][3][4][4] = 1;

    }

    public static void randomFill(int[][][][] w) {
        Random random = new Random();
        for (int[][][] w2 : w) {
            for (int[][] w3 : w2) {
                for (int[] w4 : w3) {
                    for (int i = 0; i < w4.length; i++) {
                        w4[i] = random.nextInt();
                    }
                }
            }
        }
    }

    public static void display(int[][][][] w) {
        System.out.println("Printing---------------------------------------------------------------------------------");


        System.out.print("[\n");
        for (int[][][] w2 : w) {
            System.out.print("\t[\n");
            for (int[][] w3 : w2) {
                System.out.print("\t\t[\n");
                for (int[] w4 : w3) {
                    System.out.print("\t\t\t[");
                    for (int element : w4) {
                        System.out.print(element + " ");
                    }
                    System.out.print("]\n");
                }
                System.out.print("\t\t]\n");
            }
            System.out.print("\t]\n");
        }
        System.out.print("]\n");

    }

}

As you can see you don't have to iterate on all the sub arrays. just on the ones that have their sizes changing.

Execute it and it will be obvious.

Sign up to request clarification or add additional context in comments.

4 Comments

That works. The problem is that I get an a java.lang.ArrayIndexOutOfBoundsException: 18 in the subsequent lines when first manipulating w again
In your for loops you should use w.length. You're copying stuff so you only have to 'read' from your source. If you need to initialize the destination's element do it before the main loop also
Thank you for the illustration. But how do I make w = wNew in terms of size?
I've updated my answer again, it's been a while I haven't used plain old arrays. it happens that Systrem.arraycopy(...) don't keep the "extra" space in the indexes it copies. This mean the w[0][19] won't work but w[19][19] will with my initial answer. To fix this refers to my updated answer. You need to iterate on the changing dimensions only

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.