Array declaration and assigning values to individual slots of Arrays

Viewed 1294

I asked this question earlier and got the things clear. However, I have some doubts, explaining below:

Let us assume the need is to have an array with 100 elements in this:

1) Declare array:

Integer[] intArr;

2) Allocate memory for 100 Integer elements and assign the reference to the variable

intArr = new Integer[100];

Now comes the real doubt.

Which one is correct way of assigning values to individual elements within the array:

Approach 1:

intArr[1] = 1;

Approach 2:

intArr[1] = new Integer(1);

My doubt is that we already have allocated memory for 100 elements and if we user Approach 2 , aren't we creating one more memory area and assigning them to the intArr1?

Does intArr[index] hold the reference's address or actual object can be placed in intArr[index].

Hope to get some insight to clear this doubt.

3 Answers

Those two lines are somewhat equivalent. The first uses auto-boxing. It's actually directly equivalent to:

intArr[1] = Integer.valueOf(1);

The difference is that this can reuse references to the same Integer object multiple times, whereas in your second approach you're creating a new Integer object. You can see the difference here:

intArr[1] = Integer.valueOf(1);
intArr[2] = Integer.valueOf(1);
System.out.println(intArr[1] == intArr[2]); // True, references to the same object

intArr[1] = new Integer(1);
intArr[2] = new Integer(1);
System.out.println(intArr[1] == intArr[2]); // False, references to the different objects

In all cases, the values of the array are references. They are never the objects themselves. When you allocate the array, that's creating enough space for 100 references, and those references are initially all null.

If you want an array that contains the integer data directly, just use an int[] instead of Integer[].

My doubt is that we already have allocated memory for 100 elements and if we user Approach 2 , aren't we creating one more memory area and assigning them to the intArr1?

The memory you've allocated in new Integer[100] is for the 100 object references the array will contain, not the objects it contains. When adding to the array, since it's an array of objects, you still have to create the object.

Your approaches are actually essentially the same under the covers because the compiler will automatically "box" 1 in Approach 1 via Integer.valueOf(1), changing:

intArr[1] = 1;

to

intArr[1] = Integer.valueOf(1);

(Even when not relying on autoboxing, Integer.valueOf is generally the better way to get an Integer instance, since it may cache them [and always caches instances for -128 through 127].)

Let's follow it through with some ASCII-art:

When you do:

Integer[] intArr;

you have something like this in memory:

intArr[null]

E.g., a variable containing null. Now you allocate the memory for the array and assign it to the variable:

intArr = new Integer[100];

and you get something like this:

                     +−−−−−−−−−−−−−−−−+
intArr[Ref21345]−−−−>|  Integer[100]  |
                     +−−−−−−−−−−−−−−−−+
                     |  0: null       |
                     |  1: null       |
                     | ...            |
                     | 99: null       |
                     +−−−−−−−−−−−−−−−−+

Now we have room to store 100 object references; they all start out null. Then you do:

intArr[0] = 1;

which the compiler turns into

intArr[0] = Integer.valueOf(1);

and you get:

                     +−−−−−−−−−−−−−−−−+
intArr[Ref21345]−−−−>|  Integer[100]  |
                     +−−−−−−−−−−−−−−−−+     +−−−−−−−−−−+
                     |  0: [Ref84651] |−−−−>| Integer  |
                     |  1: null       |     +−−−−−−−−−−+
                     | ...            |     | value: 1 |
                     | 99: null       |     +−−−−−−−−−−+
                     +−−−−−−−−−−−−−−−−+

Just to elaborate.

If you say

int[] vals = new int[10];

You are allocating space for 10 integers. Which means that memory allocated here is 10* 32 bits.

Integer[] vals = new Integer[10].

The memory allocated here is nothing (other than the array object itself.). All the elements inside array are null's and won't carry any memory yet.

So when you do

intArr[1] = new Integer(1);

Memory allocated for new Integer(1) and the reference been given to the index of intArr, so you actually allocating memory only once.

Even though you are doing

intArr[1] = 1;

It actually auto boxed to Integer and stores that reference.

Related