4.3. Arrays

[4.1] Declare, instantiate, initialize, and use a one-dimensional array

[4.2] Declare, instantiate, initialize, and use a multidimensional array

In this section, I’ll cover declaration, allocation, and initialization of one-dimensional and multidimensional arrays. You’ll learn about the differences between arrays of primitive data types and arrays of objects.

4.3.1. What is an array?

An array is an object that stores a collection of values. The fact that an array itself is an object is often overlooked. I’ll reiterate: an array is an object itself; it stores references to the data it stores. Arrays can store two types of data:

  • A collection of primitive data types
  • A collection of objects

An array of primitives stores a collection of values that constitute the primitive values themselves. (With primitives, there are no objects to reference.) An array of objects stores a collection of values, which are in fact heap-memory addresses or pointers. The addresses point to (reference) the object instances that your array is said to store, which means that object arrays store references (to objects) and primitive arrays store primitive values.

The members of an array are defined in contiguous (continuous) memory locations and hence offer improved access speed. (You should be able to quickly access all the students of a class if they all can be found next to each other.)

The following code creates an array of primitive data and an array of objects:

I’ll discuss the details of creating arrays shortly. The previous example shows one of the ways to create arrays. Figure 4.19 illustrates the arrays intArray and objArray. Unlike intArray, objArray stores references to String objects.

Figure 4.19. An array of int primitive data type and another of String objects

Note

Arrays are objects and refer to a collection of primitive data types or other objects.

In Java, you can define one-dimensional and multidimensional arrays. A one-dimensional array is an object that refers to a collection of scalar values. A two-dimensional (or more) array is referred to as a multidimensional array. A two-dimensional array refers to a collection of objects in which each of the objects is a one-dimensional array. Similarly, a three-dimensional array refers to a collection of two-dimensional arrays, and so on. Figure 4.20 depicts a one-dimensional array and multidimensional arrays (two-dimensional and three-dimensional).

Figure 4.20. One-dimensional and multidimensional (two- and three-dimensional) arrays

Note that multidimensional arrays may or may not contain the same number of elements in each row or column, as shown in the two-dimensional array in figure 4.20.

Creating an array involves three steps, as follows:

  • Declaring the array
  • Allocating the array
  • Initializing the array elements

You can create an array by executing the previous steps using separate lines of code or you can combine these steps on the same line of code. Let’s start with the first approach: completing each step on a separate line of code.

4.3.2. Array declaration

An array declaration includes the array type and array variable, as shown in figure 4.21. The type of objects that an array can store depends on its type. An array type is followed by one or more empty pairs of square brackets [].

Figure 4.21. Array declaration includes the array type and array variable

To declare an array, specify its type, followed by the name of the array variable. Here’s an example of declaring arrays of int and String values:

The number of bracket pairs indicates the depth of array nesting. Java doesn’t impose any theoretical limit on the level of array nesting. The square brackets can follow the array type or its name, as shown in figure 4.22.

Figure 4.22. Square brackets can follow either the variable name or its type. In the case of multidimensional arrays, it can follow both of them.

Note

In an array declaration, placing the square brackets next to the type (as in int[] or int[][]) is preferred because it makes the code easier to read by showing the array types in use.

The array declaration only creates a variable that refers to null, as shown in figure 4.23.

Figure 4.23. Array declaration creates a variable that refers to null.

Because no elements of an array are created when it’s declared, it’s invalid to define the size of an array with its declaration. The following code won’t compile:

An array type can be any of the following:

  • Primitive data type
  • Interface
  • Abstract class
  • Concrete class

We declared an array of an int primitive type and a concrete class String previously. I’ll discuss some complex examples with abstract classes and interfaces in section 4.3.7.

Note

Arrays can be of any data type other than null.

4.3.3. Array allocation

As the name suggests, array allocation will allocate memory for the elements of an array. When you allocate memory for an array, you should specify its dimensions, such as the number of elements the array should store. Note that the size of an array can’t expand or reduce once it is allocated. Here are a few examples:

Because an array is an object, it’s allocated using the keyword new, followed by the type of value that it stores, and then its size. The code won’t compile if you don’t specify the size of the array or if you place the array size on the left of the = sign, as follows:

The size of the array must evaluate to an int value. You can’t create an array with its size specified as a floating-point number. The following line of code won’t compile:

Java accepts an expression to specify the size of an array, as long as it evaluates to an int value. The following are valid array allocations:

Let’s allocate the multidimensional array multiArr, as follows:

You can also allocate the multidimensional array multiArr by defining size in only the first square brackets:

It’s interesting to note the difference between what happens when the multidimensional array multiArr is allocated by defining sizes for a single dimension or for both of its dimensions. This difference is shown in figure 4.24.

Figure 4.24. The difference in array allocation of a two-dimensional array when it’s allocated using values for only one of its dimensions and for both of its dimensions

You can’t allocate a multidimensional array as follows:

won’t compile because there’s a mismatch in the number of square brackets on both sides of the assignment operator (=). The compiler required [][] on the right side of the assignment operator, but it finds only []. won’t compile because you can’t allocate a multidimensional array without including a size in the first square bracket and defining a size in the second square bracket.

Once allocated, the array elements store their default values. For arrays that store objects, all the allocated array elements store null. For arrays that store primitive values, the default values depend on the exact data types stored by them.

Exam Tip

Once allocated, all the array elements store their default values. Elements in an array that store objects default to null. Elements of an array that store primitive data types store 0 for integer types (byte, short, int, long); 0.0 for decimal types (float and double); false for boolean; or u0000 for char data.

4.3.4. Array initialization

You can initialize an array as follows:

In the preceding code, uses a for loop to initialize the array intArray with the required values. initializes the individual array elements without using a for loop. Note that all array objects use their public immutable field length to access their array size.

Similarly, a String array can be declared, allocated, and initialized as follows:

When you initialize a two-dimensional array, you can use nested for loops to initialize its array elements. Also notice that to access an element in a two-dimensional array, you should use two array position values, as follows:

What happens when you try to access a nonexistent array index position? The following code creates an array of size 2 but tries to access its array element at index 3:

The previous code will throw a runtime exception, ArrayIndexOutOfBounds-Exception. For an array of size 2, the only valid index positions are 0 and 1. All the rest of the array index positions will throw the exception ArrayIndexOutOfBoundsException at runtime.

Note

Don’t worry if you can’t immediately absorb all the information related to exceptions here. Exceptions are covered in detail in chapter 7.

The Java compiler doesn’t check the range of the index positions at which you try to access an array element. You may be surprised to learn that the following line of code will compile successfully even though it uses a negative array index value:

Although the previous code compiles successfully, it will throw the exception Array-IndexOutOfBoundsException at runtime. Code to access an array element will fail to compile if you don’t pass it a char, byte, short, or int data type (wrapper classes are not on this exam, and I don’t include them in this discussion):

Exam Tip

Code to access an array index will throw a runtime exception if you pass it an invalid array index value. Code to access an array index will fail to compile if you don’t use a char, byte, short, or int.

Also, you can’t remove array positions. For an array of objects, you can set a position to the value null, but it doesn’t remove the array position:

creates an array of String and initializes it with four String values. sets the value at array index 2 to null. iterates over all the array elements. As shown in the following output, four (not three) values are printed:

Autumn
Summer
null
Winter

4.3.5. Combining array declaration, allocation, and initialization

You can combine all the previously mentioned steps of array declaration, allocation, and initialization into one step, as follows:

int intArray[] = {0, 1};
String[] strArray = {"Summer", "Winter"};
int multiArray[][] = { {0, 1}, {3, 4, 5} };

Notice that the previous code

  • Doesn’t use the keyword new to initialize an array
  • Doesn’t specify the size of the array
  • Uses a single pair of braces to define values for a one-dimensional array and multiple pairs of braces to define a multidimensional array

All the previous steps of array declaration, allocation, and initialization can be combined in the following way, as well:

int intArray2[] = new int[]{0, 1};
String[] strArray2 = new String[]{"Summer", "Winter"};
int multiArray2[][] = new int[][]{ {0, 1}, {3, 4, 5}};

Unlike the first approach, the preceding code uses the keyword new to initialize an array.

If you try to specify the size of an array with the preceding approach, the code won’t compile. Here are a few examples:

int intArray2[] = new int[2]{0, 1};
String[] strArray2 = new String[2]{"Summer", "Winter"};
int multiArray2[][] = new int[2][]{ {0, 1}, {3, 4, 5}};
Exam Tip

When you combine an array declaration, allocation, and initialization in a single step, you can’t specify the size of the array. The size of the array is calculated by the number of values that are assigned to the array.

Another important point to note is that if you declare and initialize an array using two separate lines of code, you’ll use the keyword new to initialize the values. The following lines of code are correct:

int intArray[];
intArray = new int[]{0, 1};

But you can’t miss the keyword new and initialize your array as follows:

int intArray[];
intArray = {0, 1};

4.3.6. Asymmetrical multidimensional arrays

At the beginning of this section, I mentioned that a multidimensional array can be asymmetrical. An array can define a different number of columns for each of its rows.

The following example is an asymmetrical two-dimensional array:

String multiStrArr[][] = new String[][]{
                                        {"A", "B"},
                                        null,
                                        {"Jan", "Feb", "Mar"},
                                    };

Figure 4.25 shows this asymmetrical array.

Figure 4.25. An asymmetrical array

As you might have noticed, multiStrArr[1] refers to a null value. An attempt to access any element of this array, such as multiStrArr[1][0], will throw an exception. This brings us to the next Twist in the Tale exercise (answers are in the appendix).

Twist in the Tale 4.3

Modify some of the code used in the previous example as follows:

Line1> String multiStrArr[][] = new String[][]{
Line2>                                        {"A", "B"},
Line3>                                        null,
Line4>                                        {"Jan", "Feb", null},
Line5>                                        };

Which of the following individual options are true for the previous code?

  1. Code on line 4 is the same as {"Jan", "Feb", null, null},.
  2. No value is stored at multiStrArr[2][2].
  3. No value is stored at multiStrArr[1][1].
  4. Array multiStrArr is asymmetric.

4.3.7. Arrays of type interface, abstract class, and class Object

In the section on array declaration, I mentioned that the type of an array can also be an interface or an abstract class. What values do elements of these arrays store? Let’s look at some examples.

interface type

If the type of an array is an interface, its elements are either null or objects that implement the relevant interface type. For example, for the interface MyInterface, the array interfaceArray can store references to objects of either the class MyClass1 or MyClass2:

interface MyInterface {}
class MyClass1 implements MyInterface {}

class MyClass2 implements MyInterface {}
class Test {
MyInterface[] interfaceArray = new MyInterface[]
                                  {
                                      new MyClass1(),
                                      null,
                                      new MyClass2()
                                  };
}
abstract class type

If the type of an array is an abstract class, its elements are either null or objects of concrete classes that extend the relevant abstract class:

Next, I’ll discuss a special case in which the type of an array is Object.

Object

Because all classes extend the class java.lang.Object, elements of an array whose type is java.lang.Object can refer to any object. Here’s an example:

is valid code. Because an array is an object, the element of the array of java.lang.Object can refer to another array. Figure 4.26 illustrates the previously created array, objArray.

Figure 4.26. An array of class Object

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.61.81