Please support my sponors and make this site possible!!!
Please support our sponsors!

 

Home > Core Java FAQ > Language Fundamentals FAQ 
Java Fundamentals
Basic(19) * Constants and Expressions(40) *  Variables and Methods(16) * Array(11) * Date/Time(36) * Compile Time(11) * Run Time(02) * C-vs-Java(12) 
 
Q . Can I allocate an array dynamically?

Ans : 

Yes and no; you can create an array with a size determined at run time, but you cannot change the size of an array once you've created it.

     Arrays in Java are full-fledged, object citizens of the language. Like other Java objects, they are created dynamically at run time, and their storage space is allocated from the virtual machine's system storage. Because arrays are created at run time, you don't have to prespecify an array's size at compile time.
     There are two ways to create an array: with an array initializer when declaring an array-type variable, or with an array creation expression. An array initializer specifies the complete set of values to be stored in an array. For example, the following declaration and initializer create an array holding 5 int values:

     int[] myInts = {5, 4, 3, 2, 1};  // int  myInts[]... also allowed

     A plain array creation expression, using the new keyword, creates an array filled with default values for the element type in the array. You specify the size of the array with any expression that evaluates to an int. The following code, for instance, creates an array of sine values; the array's size is specified by the method's argument:

     public static float[] sineArray(int size) {
         float[] sineVals = new float[size];
         for (int i = 0; i < sineVals.length; ++i) {
             sineVals[i] = (float) Math.sin( (i * 2 * Math.PI) / size);
         }
         return sineVals;
     }

     Starting with the JDK 1.1, you can also include an array initializer directly in an array creation expression. For example:

     /* using JDK 1.1: */
     // int[] myInts declared elsewhere
     myInts = new int[] {5, 4, 3, 2, 1};

     Once a Java array is created, its size is fixed for the lifetime of the array. If you need more dynamism-an array-like object that can grow as needed when you use it-consider using the Vector class in the java.util package.

Q . How do I allocate a multidimensional array?

Ans : There are several ways. If you want a rectangular array, you can allocate the space for the array all at once. The following creates a 4x5 array:

int arr[][] = new int[4][5];

If you want each row to have a different number of columns, you can use the fact that a two-dimensional array is actually an array of arrays.The following code allocates a triangular array:

int arr[][] = new int[4][]; // allocate the four row arrays
for (int i = 0; i < 4; i++) // initialize each of the four rows
arr[i] = new int[i + 1]; // row i has i + 1 columns

Note that if you allocate an array of any kind of object (as opposed to primitive type), all the references will be null by default. These null references can result in NullPointerExceptions if you try to deference them. In other words, after doing:

int arr[] = new int[4]; 

you can say
if (arr[2] == 0)

But after doing
Integer Iarr[] = new Integer[4];

you must fill in the object reference before using it. E.g.,
Iarr[2] = myInt;
or
arr[2] = new Int(27);

before you can say
if (Iarr[2].equals(myInt))

Q . How do I initialize an array of objects?

Ans :  

Write a loop that initializes the base elements of your array one by one.

     In the Java language, what looks like an array of objects is really an array of object references— basically, pointers to objects. The objects themselves are stored separately in space managed by the Java Virtual Machine. When you create an object-type array, you are in fact creating an array of object references. Unless you explicitly initialize the array, moreover, each object reference receives the default initial value of null. In other words, creating an object array in Java automatically gives you an array filled with null object references.
     After creating an array, you need to set each object reference to refer to some bona fide object. The usual technique for this is to allocate and initialize objects in a loop through the array, as illustrated:

     String[] sArray = new String[10];
     for (int i = 0; i < sArray.length; ++i) {
         sArray[i] = "string at index " + i;
     }

     The behavior of arrays containing objects follows from the fact that Java array components are in fact nameless variables (The Java Language Specification, p. 193). These nameless variables are related to their array in much the same way that (named) instance variables are related to the class instance containing them. Table 2.7 compares arrays and class instances as two different kinds of object; you might find this alternate view of Java arrays a surprising yet useful one.

Table 2.7: Class versus Array as Two Kinds of Object

Class instance (obj) Array instance (arr)
stores per-object data in named instance variables stores per-object data in nameless (but numbered) variables
can have variables of different types in one object all variables in object have same type
accesses variables by name: obj.fieldName accesses variables by index: arr[index]
reference-type variables hold object references [same as class instance]
instance variables have default initialization [same as class instance
Q . How do I copy an array?

Ans : If the array only contains primitive types or if you want to copy only the object references, not duplicate the objects, then use the method

java.lang.System.arraycopy(Object src, int src_position,
Object dst, int dst_position, int length);

Otherwise, if you want to duplicate the objects, you have to initialize your new array and write a loop that duplicates each object in the old array into the new.

Note that the documentation for arraycopy() says that if src and dst refer to the same object, then arraycopy behaves as if the source array elements are copied into a temporary array (i.e., they are preserved). Some interpret this as meaning a temporary array will be so allocated, but that's not Sun's implementation.

Q . How do I clear an array?

Ans : There is no method to clear an array to 0.0, 0, null, false, '\u0000' etc. When you allocate an array, the elements are set to their default values, but that doesn't help when you want to reuse an array.

If you want to set the same array to the same set of values many times, create a template array. Fill it with the reset value, then use System.arraycopy() to copy it into the work array each time you need to
set the work array.

Q . If arrays are objects, why can't I use a length method to determine an array's size?

Ans :  

Such a method would be reasonable, but it doesn't exist; the Java language designers decided to expose array length like a public final instance variable rather than a method.

     In Java, arrays are objects. They are created dynamically from central, system-managed memory like other objects; they all have Object as a superclass; and you can invoke any Object method on them. Given this, it would have been possible to define a length instance method on arrays to return the length of the array, much like the length method in class String.
     However, the Java language designers chose to represent length simply as an instance variable of the array. The length variable is always accessible but never changeable; its value is fixed at the time the array is created.

Q . Why can't I do myArray.length() ? Arrays are just objects, right?

Ans : Yes, the Java specification says that arrays are object references [JLS 10.2] just like classes are. However, arrays cannot contain methods. Instead you have to use myArray.length, which is a data item
(not a method) called "length", belonging to myArray.

Q . NullPointerExceptions with arrays of objects?

Ans : When you allocate an array of objects, each component of the array is initialized to null. The individual components of the array must still be initialized with a constructor or an assignment statement. For example, consider this statement:

Integer[] scores = new Integer[10];
int m = scores[5].intValue(); // throws NullPointerException

This creates an array called scores containing ten references to Integer objects. Then it tries to get the value of the fifth component. However, each of those references is initially set to null. Thus when you try to call a method on one of the components of the array or pass the component to a method that expects a non-null argument, a NullPointerException is thrown. 
To fix this, you need to initialize the components of the array, either with constructors or with assignment statements For example:

Integer[] scores = new Integer[10];
for (int i = 0; i < scores.length; i++) scores[i] = new Integer(i);
int m = scores[5].intValue(); 

You do not need to initialize all the components of the array though it's a good idea to do so. You can initialize just those you'll use, or you can make sure you catch and handle NullPointerExceptions in the appropriate places.
This is different from how Java handles uninitialized non-array reference variables. By way of contrast when you write,

Integer score;
int m = score.intValue();

the compiler catches the null reference in score and complains. You have to fix the problem before you can compile the program. However in general the compiler has no way to know whether an array component has or has not been initialized. Therefore the check for the non-nullness of an array component is deferred till runtime when the NullPointerException may be thrown.

Q . What is a fast way to set all elements of an array?

Ans : Using a loop that does it one by one is probably 20 to 40 times slower than good old memset() in C.

A fast way on many VM's is to set the first byte of the array, then use System.arraycopy() repeatedly to fill the next byte, the next two bytes, the next four bytes, the next eight bytes, etc., and when you get past halfway, fill in the rest.

public static void bytefill(byte[] array, byte value) {
int len = array.length;
if (len > 0)
array[0] = value;
for (int i = 1; i < len; i += i)
        System.arraycopy( array, 0, array, i, ((len - i) < i) ? (len - i) : i);
}

This is faster on Sun's VM than a simple loop, and probably even faster under JITs because it only performs at most log2(array.length) bounds checks. This is a clever code idiom applying the binary chop algorithm to arrays even when their size is not a power of 2.

Q . When I change a field in just one object in my array, that field changes in all the objects in my array?

Ans : Here the problem is probably that you have initialized the array with N references to the same one object.

This is easy to overlook, because arrays in Java only contain references to objects, not objects. (Or they can contain primitives).

Q . How do you deallocate an array in Java?

Ans : Java uses automatic garbage collection and does not support C++'s delete or delete[]. If the last reference to an object is removed, the object will be garbage collected. If the variable referring to an array becomes out of scope, its reference is lost. (Note that an array is an object in Java). Or you can assign null to the variable directly. 

 

Copyright © 2000 javafaq.com. All rights reserved