Array Initialization
Array initialization in C is very error-prone and troublesome. C ++ makes it safer through "set initialization" (note 6 ). Java does not have the "set" concept like C ++, because everything in Java is an object. But it does have its own array, which is supported through array initialization.
An array represents a series of objects or basic data types. All the same types are encapsulated together. A uniform identifier name is used. The array is defined and used through the square brackets index operator ([]). To define an array, simply follow a pair of empty square brackets after the type name:
Int [] Al;
You can also place square brackets after the identifiers to obtain completely consistent results:
Int al [];
This format is consistent with the format used by C and C ++ programmers. However, the most "fluent" may be the previous syntax, because it indicates that the type is "an int array ". This book will follow that format.
The compiler does not allow us to tell it how big an array is. This will bring us back to the "handle" issue. In this case, all we have is a handle pointing to the array, and no space has been allocated to the array. To create a bucket for an array, you must write an initialization expression. For arrays, initialization can appear anywhere in the code, but you can also use a special initialization expression, which must appear anywhere the array is created. This special Initialization is a series of values closed by curly braces. The distribution of buckets (equivalent to using new) will be performed by the compiler in this case. For example:
Int [] a1 = {1, 2, 3, 4, 5 };
So why do we need to define an array handle without an array?
Int [] A2;
In fact, one array can be allocated to another in Java, so the following statement can be used:
A2 = A1;
What we really want to do is to copy a handle, as shown below:
//: Arrays.java// Arrays of primitives.public class Arrays { public static void main(String[] args) { int[] a1 = { 1, 2, 3, 4, 5 }; int[] a2; a2 = a1; for(int i = 0; i < a2.length; i++) a2[i]++; for(int i = 0; i < a1.length; i++) prt("a1[" + i + "] = " + a1[i]); } static void prt(String s) { System.out.println(s); }} ///:~
We can see that A1 gets an initial value, but A2 does not; a2 will assign a value later -- in this case, it is assigned to another array.
There are also some new things: All arrays have an essential member (whether it is an object array or an array of basic types), which can be queried-but not changed, the number of elements in the array is determined. This member is length. Similar to C and C ++, because the Java array starts counting from element 0, the maximum element number that can be indexed is "length-1 ". If the boundary is exceeded, C and C ++ will "Silently" accept and allow us to use our memory randomly, which is the root cause of many program errors. However, Java can retain the damage caused by this problem by generating a runtime error once the boundary is exceeded (that is, an "violation", which is the subject of chapter 1 ). Of course, because you need to check the access to each array, it will consume a certain amount of time and extra code, and there is no way to close it. This means that array access may be an important cause of low program efficiency-if they are used in critical scenarios. But considering the security of Internet access and the programming efficiency of programmers, Java designers should regard it as worthwhile.
What should I do if I don't know how many elements are needed in my array during programming? In this case, you only need to use new to create elements in the array. Here, even if you want to create an array of the basic data type, new can work normally (New will not create a basic type of non-array ):
//: ArrayNew.java// Creating arrays with new.import java.util.*;public class ArrayNew { static Random rand = new Random(); static int pRand(int mod) { return Math.abs(rand.nextInt()) % mod + 1; } public static void main(String[] args) { int[] a; a = new int[pRand(20)]; prt("length of a = " + a.length); for(int i = 0; i < a.length; i++) prt("a[" + i + "] = " + a[i]); } static void prt(String s) { System.out.println(s); }} ///:~
Since the size of the array is determined randomly (using the prand () method previously defined), it is obvious that the creation of the array is actually performed during the runtime. In addition, from the output of this program, we can see that the array elements of the basic data type are automatically initialized as "null" values (For numeric values, the null value is zero; for char, it is null, but it is false for Boolean ).
Of course, arrays may have been defined and initialized in the same statement, as shown below:
Int [] A = new int [prand (20)];
If the operation is an array of non-basic type objects, use new in any case. Here, we will encounter the handle problem again, because we create a handle array. Please observe the encapsulation type Integer, which is a class rather than a basic data type:
//: ArrayClassObj.java// Creating an array of non-primitive objects.import java.util.*;public class ArrayClassObj { static Random rand = new Random(); static int pRand(int mod) { return Math.abs(rand.nextInt()) % mod + 1; } public static void main(String[] args) { Integer[] a = new Integer[pRand(20)]; prt("length of a = " + a.length); for(int i = 0; i < a.length; i++) { a[i] = new Integer(pRand(500)); prt("a[" + i + "] = " + a[i]); } } static void prt(String s) { System.out.println(s); }} ///:~
Here, you can create an array even after calling New:
Integer [] A = new integer [prand (20)];
It is only an array of handles, and the initialization process will not end unless the object handle is initialized by creating a new integer object:
A [I] = new INTEGER (prand (500 ));
However, if you forget to create an object, you will get an "violation" error when trying to read an empty array location at runtime.
Let's take a look at the composition of the string object in the print statement. As you can see, the handle pointing to the integer object is automatically converted to generate a string, which represents the value inside the object.
You can also use the curly brackets closed list to initialize the object array. Two forms are available. The first is the unique form allowed by Java 1.0. The second (equivalent) form is supported since Java 1.1:
//: ArrayInit.java// Array initializationpublic class ArrayInit { public static void main(String[] args) { Integer[] a = { new Integer(1), new Integer(2), new Integer(3), }; // Java 1.1 only: Integer[] b = new Integer[] { new Integer(1), new Integer(2), new Integer(3), }; }} ///:~
This method is useful most of the time, but the limit is also the largest, because the size of the array is determined during compilation. The last comma in the initialization list is optional (this feature makes maintenance of the long list easier ).
The second form of array initialization (supported at the beginning of Java 1.1) provides a simpler syntax for creating and calling methods, obtain the same effect as C's "Variable Parameter List" (C usually referred to as "variable parameter table. These effects include the number of unknown parameters (independent variables) and unknown types (if so selected ). Since all classes are ultimately inherited from common root class objects, you can create a method to obtain an object array and call it as follows:
//: VarArgs.java// Using the Java 1.1 array syntax to create// variable argument listsclass A { int i; }public class VarArgs { static void f(Object[] x) { for(int i = 0; i < x.length; i++) System.out.println(x[i]); } public static void main(String[] args) { f(new Object[] { new Integer(47), new VarArgs(), new Float(3.14), new Double(11.11) }); f(new Object[] {"one", "two", "three" }); f(new Object[] {new A(), new A(), new A()}); }} ///:~
At this time, we cannot take too many operations on these unknown objects, and this program uses automatic String Conversion to do some useful things for each object. In Chapter 11th (runtime type identification or rtti), you will also learn how to investigate the exact types of such objects so that you can do something interesting about them.
Multi-dimensional array
You can easily create multidimensional arrays in Java:
//: MultiDimArray.java// Creating multidimensional arrays.import java.util.*;public class MultiDimArray { static Random rand = new Random(); static int pRand(int mod) { return Math.abs(rand.nextInt()) % mod + 1; } public static void main(String[] args) { int[][] a1 = { { 1, 2, 3, }, { 4, 5, 6, }, }; for(int i = 0; i < a1.length; i++) for(int j = 0; j < a1[i].length; j++) prt("a1[" + i + "][" + j + "] = " + a1[i][j]); // 3-D array with fixed length: int[][][] a2 = new int[2][2][4]; for(int i = 0; i < a2.length; i++) for(int j = 0; j < a2[i].length; j++) for(int k = 0; k < a2[i][j].length; k++) prt("a2[" + i + "][" + j + "][" + k + "] = " + a2[i][j][k]); // 3-D array with varied-length vectors: int[][][] a3 = new int[pRand(7)][][]; for(int i = 0; i < a3.length; i++) { a3[i] = new int[pRand(5)][]; for(int j = 0; j < a3[i].length; j++) a3[i][j] = new int[pRand(5)]; } for(int i = 0; i < a3.length; i++) for(int j = 0; j < a3[i].length; j++) for(int k = 0; k < a3[i][j].length; k++) prt("a3[" + i + "][" + j + "][" + k + "] = " + a3[i][j][k]); // Array of non-primitive objects: Integer[][] a4 = { { new Integer(1), new Integer(2)}, { new Integer(3), new Integer(4)}, { new Integer(5), new Integer(6)}, }; for(int i = 0; i < a4.length; i++) for(int j = 0; j < a4[i].length; j++) prt("a4[" + i + "][" + j + "] = " + a4[i][j]); Integer[][] a5; a5 = new Integer[3][]; for(int i = 0; i < a5.length; i++) { a5[i] = new Integer[3]; for(int j = 0; j < a5[i].length; j++) a5[i][j] = new Integer(i*j); } for(int i = 0; i < a5.length; i++) for(int j = 0; j < a5[i].length; j++) prt("a5[" + i + "][" + j + "] = " + a5[i][j]); } static void prt(String s) { System.out.println(s); }} ///:~
The length is used in the printed code, so it does not have to depend on a fixed array size.
The first example shows a multi-dimensional array of the basic data type. We can use curly brackets to determine the boundary of each vector in the array:
Int [] [] a1 = {
{1, 2, 3 ,},
{4, 5, 6 ,},
};
Each square brackets moves us to the next level of the array.
The second example shows a three-dimensional array allocated with new. Here, the entire array is allocated immediately:
Int [] [] [] a2 = new int [2] [2] [4];
However, the third example shows that each vector in the matrix can have any length:
int[][][] a3 = new int[pRand(7)][][]; for(int i = 0; i < a3.length; i++) { a3[i] = new int[pRand(5)][]; for(int j = 0; j < a3[i].length; j++) a3[i][j] = new int[pRand(5)]; }
For the first new array, the length of the first element is random, and the length of other elements is not defined. The second new in the For Loop will fill in the element, but keep the status of the third index undefined until the third new is encountered.
Based on the output results, we can see that if the initialization value is not explicitly specified, the array value will be automatically initialized to zero.
You can use a similar table to process arrays of non-basic objects. As shown in the fourth example, it demonstrates the ability to collect multiple new expressions with curly brackets:
Integer[][] a4 = { { new Integer(1), new Integer(2)}, { new Integer(3), new Integer(4)}, { new Integer(5), new Integer(6)}, };
The fifth example shows how to gradually build an array of non-basic types of objects:
Integer[][] a5; a5 = new Integer[3][]; for(int i = 0; i < a5.length; i++) { a5[i] = new Integer[3]; for(int j = 0; j < a5[i].length; j++) a5[i][j] = new Integer(i*j); }
I * j only sets an interesting value in integer.