Array of arrays

What are the considerations when using an array of arrays?

Q: How do I use an array of arrays?


String s = new String( "Hello, World" );
// s is a String reference, which refers to a
// String object with value "Hello, World."
s= new String( "Guten Tag, Welt" );
// The same String reference s now refers
// to a different String object; that is,
// a single reference has referred to two
// different objects (consecutively).
// (Notice that we now have a String object
//  with value "Hello, World", which has no
// references; therefore this object is eligible
// to be garbage collected)
String t;
// t is a String reference with a null value 
// (not referring to any object).
// If you try to use t at this point, e.g. by 
// saying int len = t.length; you will get a
// NullPointerException (should be called 
// NullReferenceException).
t = s;
// The String reference t now refers to the same
// object referred to by the String reference s,
// namely a String object with the value "Guten Tag, Welt".
// So here we have two
// references to a single object (concurrently).

Arrays in Java are objects in their own right, whether they contain primitives (ints, chars, booleans, and so on) or contain other objects. This means that arrays are referred to like any other object, with the addition of the [] aggregation/dereference semantics. Here's an example:

String [] sa;
// sa is a null reference
// trying to access sa.length causes a NullPointerException.
sa = new String [2];
// sa is no longer a null reference, it refers to a specific 
// object that is an array of two null String references.
// sa.length is now equal to 2
// (sa[0] and sa[1] are the two null String references).
sa[0] = "Hello, World";
sa[1] = "Guten Tag, Welt";
// Now sa refers to an array of two non-null String references.
sa = new String[1];
// sa.length equals 1
// The same reference sa now refers to a different
// (and shorter) array.
// sa[0] is a null String reference
// trying to access sa[1] causes an
// ArrayIndexOutOfBoundsException.
sa[0] = "Hello, World";
// sa[0] is now non-null.

Your question about arrays can be answered by considering that

String [] [] saa;
saa [0] [0] = "Help";

will cause a NullPointerException, because saa is a null reference -- that is, saa doesn't refer to any object. In order to assign a value to the first element of the first array, saa must refer to an array of with a length greater than zero, and saa[0] must refer to a nonnull string array the length of which is also greater than zero. So, one could start by saying:

String [] [] saa;
// saa is a null reference to an array of String arrays
// Trying saa.length already causes a NullPointerException,
// like trying saa[0] does.
saa = new String [1][];
// saa now refers to an array of 1 null reference to a String[].
// saa.length is equal to 1.
// saa[0] is null.
saa[0] = new String[2];
// saa now refers to an array of 1 non-null reference 
// to a String[] of length 2.
// saa.length is still equal to 1.
// saa[0].length is equal to 2 (but saa[0][0] and 
// saa[0][1] are both null).
saa[0][0] = "Hello, World";
saa[0][1] = "Guten Tag, Welt";
// Now saa[0][0] and saa[0][1] are both non-null.

Notice that you cannot refer to saa[0][0] until saa[0] is nonnull, and you can't make saa[0] nonnull until you make saa nonnull. Basically, you have to build up your array of arrays incrementally.

There is an easy-to-use shorthand for initializing array references:

String [][] saa = {
   { { "Hello, World }, { "Guten Tag, Welt"} } };
   // this creates a String[][] object like the one created
   // above, and assigns saa to refer to that object.
   // The whitespace is meant to emphasize that the
   // object created is an array of one String[] which
   // contains two Strings.

Using this shorthand, our example could correctly be written as:

String [][] saa = { { { "Help" } } };

However, this makes saa refer to a one by one string array. Note that the syntax above only works when initializing an array reference (initialization is the special case of assignment at the time of declaration). The more general way to create a new array and assign it to a new or existing array reference looks like this (in the case of an existing reference):

saa = new String [][] {
// note the empty [][] -- the compiler figures the
// size out (empty [][] is required).
   {  { "Hello" }, { "World" }  }  // this is saa[0]
                                        ,  // note the comma separating
saa[0] and saa[1]
                                        {  { "Guten Tag" },    { "Welt"
}  }  // this is saa[1]
    // now saa.length = 2, and saa[0] and saa[1] also each have length 2
Random Walk Computing is the largest Java/CORBA consulting boutique in New York, focusing on solutions for the financial enterprise. Known for their leading-edge Java expertise, Random Walk consultants publish and speak about Java in some of the most respected forums in the world.