Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is declaring an empty array of non-empty array(s) legal in Java?

Curious why declaring an empty array of non-emtpy array(s) is legal in Java:

int[][] array = new int[0][1];

System.out.println(array[][0]); //won't compile.
System.out.println(array[0][0]) //triggers an out of bounds exception.

P.S. I have read the related question on zero-size arrays: Why does Java allow arrays of size 0?

Is this for the same reason?

like image 450
Pavlo Maistrenko Avatar asked Jul 05 '20 06:07

Pavlo Maistrenko


2 Answers

An int[][] array is an array whose elements are int[] (i.e. its elements are arrays of int).

Just like you are allowed to define an empty array of int elements:

int[] empty = new int[0];

or an empty array of String elements:

String[] empty = new String[0];

You are also allowed to define an empty array of int[1] elements:

int[][] empty = new int[0][1];

Perhaps it's the syntax that is somewhat confusing here.

If it was

int[][] empty = new (int[1])[0]

it would be clearer that you are defining an empty array whose element type is int[1].

However, since the number in the first square brackets represents the number of elements in the outer array, new int[1][0] does not represent an empty array, but an array of a single element (whose single element is an empty int array).

like image 75
Eran Avatar answered Oct 12 '22 15:10

Eran


It is legal to define empty arrays in general, no matter what it contains. Thus, it is also legal to have an empty array containing non empty arrays.

Mathematically (group theory) speaking, empty arrays are not only legal, but necessary, since they represent the zero (or neutral) element of array concatenation operation. This also makes it useful for programming (see the example below).

In your example you basically probe, if it is ok to access elements of an empty array. This is of course not legal, since there are none. However you can do:

int[][] array = new int[0][1];
System.out.println(array.length);

With reference to my own example above, a more useful case is:

    int[][] array1 = new int[1][1];
    int[][] array2 = new int[0][1];

    array1[0][0] = 1;

    int [][] concat = Stream
            .concat(Arrays.stream(array1), Arrays.stream(array2))
            .toArray(int[][]::new);

    System.out.println(Arrays.deepToString(concat));

Thus empty arrays allow to for "good" code, without ifs to exclude, illegal cases, which actually are totally fine.

like image 33
PeMa Avatar answered Oct 12 '22 15:10

PeMa