![]() |
|||
![]() ![]() |
![]() |
|
![]() |
StringsThe final thing that all objects must be able to do is to provide a string representation of themselves. They can do this with the toString() method. The default toString() method from the java.lang.Object class merely prints the name of the class of the object. Most classes will override this method with one that provides more information. The toString() method is rarely called explicitly. It is instead invoked implicitly when an object is passed as an argument into a print() method or is concatenated with a string using a + sign. Ill talk more about strings and toString() methods later in this chapter. ArraysWhat is an array? To a high-level programmer, an array is an indexed list of values of the same type with a fixed length. The most important feature of an array is that you can retrieve any particular element of the array in constant time. In other words, it takes no more or less time to retrieve the seventh component of the array than it takes to retrieve the 70th or the 700th.
Primitive data types like shorts and ints are stored directly in the array. They take up no more space than the array itself. In fact, an array of shorts, bytes, or chars takes up less space than the same number of short, byte, or char variables. Individual variables of these types are always promoted to ints. Thus, a byte variable occupies four bytes, and four byte variables occupy 16 bytes because each byte is promoted to an int. However, promotion does not occur inside arrays, so an array of four bytes occupies exactly four bytes. Similarly, an array of four shorts or an array of four chars occupies exactly eight bytes. Arrays of objects are a little different. Each entry in the array is not the object itself but rather a reference to the object. Each reference requires four bytes, whether or not that reference is null. However, if a component of the object array is indeed non-null, then somewhere else in the heap is an object that also needs memory. When you calculate the total memory needed for an array of objects, you have to account for the array and the objects themselves separately. For example, consider this array: Integer[] iarray = new Integer[10]; for (int i = 0; i < iarray.length; i++) { iarray[i] = new Integer(i); } By looking at the source code for the Integer class, you discover that each Integer object has a single non-static int field. Thus, each Integer object occupies four bytes of heap memory. When the Integer[] array iarray is created, it has space for ten references. This takes up 40 bytes. As new Integer objects are created and added to the array in the for loop, each of these takes an additional four bytes. When the loop is complete, the array occupies 80 bytes of the heap. If you then set some of the array components to null, the corresponding Integer objects would eventually be garbage-collected, and the array would shrink to somewhere between 40 and 80 bytes of the heap. Whether the array ever really occupies more than 40 bytes is a semantic question. You could just as reasonably say that the array always occupies 40 bytes and additional space may be occupied by the objects to which the arrays components refer. As long as you understand whats really going on, you can say it however you want. Multidimensional arraysJava does not have true multidimensional arrays like Fortran does. Instead, it fakes them with one-dimensional arrays of references to one-dimensional arrays, much in the fashion that C does. For example, consider a two-dimensional array of doubles like this: double[][] matrix = new double[4][3]; This is allocated in two parts. First, a one-dimensional, length four array of references is allocated; then, each of these is pointed at a one-dimensional, length three array of doubles. In other words: matrix = new double[4][]; for (int i = 0; i < 4; i++) matrix[i] = new double[3];
This means that even though matrix is declared as a two-dimensional array of doubles, matrix[0], matrix[1], matrix[2], and matrix[3] are all legitimate Java entities. For example, you can copy the first row of matrix into the third row using System.arraycopy() like this: System.arraycopy(matrix[1], 0, matrix[3], 0, 3); You can use matrix[0], matrix[1], matrix[2], and matrix[3] anywhere a one-dimensional array of doubles is expected. This also means you can create ragged arrays that is, arrays that do not have a fixed length in one dimension. For example, int[][] triangle = new int[12][]; for (int i = 0; i < 12; i++) { triangle[i] = new int[i+1]; } The zeroth row of the triangle array has length one, the first row has length two, the second row has length three, and so on. Higher dimensional arrays just have additional levels of indirection. For example, double[][][] Datacube = new double[4][3][7]; Datacube[0] through Datacube[3] are references to two-dimensional arrays of doubles; more precisely, theyre references to arrays of references to one-dimensional arrays of doubles. Datacube [0][2] is a reference to a one-dimensional array of doubles and can be used anywhere a one-dimensional array of doubles is needed.
|
![]() |
|