Skip to main content
gamedev.net
🔒 Locked

[java] Array weirdness!

Started by Woody FX Nov 20, 2004 at 11:18 AM 14 replies 1.3k views
Original Post
Woody FX
Woody FX
Just a little unsure in Java how exactly arrays are working? Can some explain the differences in these results


int array_1[][] = new int[8][8];
int array_2[][] = new int[8][8];

// populate both arrays with random data

array_1 = array_2;


If I make a change to array_2 the change also seems to happen in array_1! So it seems like the is pointer stuff going on. Didn’t think that happened in Java but maybe this is the case and that cool if it is as this is useful.


int array_1[][] = new int[8][8];
int array_2[][] = new int[8][8];

// populate both arrays with random data

for (int y=0; y<8; y++)
     {
     for (int x=0; x<8; x++)
          {
          array_1[y][x] = array_2[y][x];
          }
     } 


This works as expected and the arrays are total individual of each other and any changes in one array do not effect the other. But what is going on in the first example? Many Thanks, Woody
andrewk3652
andrewk3652
Well no, there aren't pointers in Java. There are references.

When you asssign new int[x][x] to an int array, you're assigning a reference to an array object. And then when you assign array_2 to array_1, you're not actually copying the data; you're assigning the reference array_1 to the same object as array_2 is referencing. So naturally, changes are reflected in both objects.

Make sense?
=========================Buildium. Codium. Fragium.http://www.aklabs.net/=========================
Miserable
Miserable
Quote:
Original post by andrewk3652
Well no, there aren't pointers in Java. There are references.

What the Java people call a "reference" is what C/C++ programmers refer to as a pointer, though. Java has no equivalent to the C++ reference.
yaroslavd
yaroslavd
No, references exist in C++.
capn_midnight
capn_midnight
all objects live on the heap, all variables of non-primitive type are Java References (aka pointers) to the object on the heap.

Arrays in java, even of primitive data types, are objects.

there are actually 2 other threads about this exact same topic in here right now.
capn_midnight
capn_midnight
Quote:
Original post by yaroslavd
No, references exist in C++.

that's not what he said
C++ has these things called references and these things called pointers.
Java has only these things called references.
The things that Java calls references are the same things that C++ calls pointers.
Therefore, Java has nothing that is equivalent to what C++ calls a reference.
Woody FX
Woody FX
Thanks ok i get it now!

Still getting used to the switch across from C++!

Thanks again! :)
TheBluMage
TheBluMage
To add a bit more, all objects in Java besides primitives (int, char, long, float, etc.) are reference variables. (This can easily confuse someone from a C/C++ background.) Example:

ObjectType myObj1 = new ObjectType();ObjectType myObj2 = new ObjectType();//At this point both myObj's reference separate, newly created objects.myObj2 = myObj1;//The reference from myObj1 is copied to myObj2, the other //object that myObj2 used to refer to will be cleaned up by the //garbage collector if no other references to it exist

If you actually want an independant copy of the array, try this:
int[] array1 = new int[256];//Here's how to copy:int[] array2 = new int[array1.length];System.arraycopy(array1, 0, array2, 0, array1.length);

Note that if it's an array of reference types, the new array will contain copies of the same references, so altering the objects referenced in either array will also affect the objects referenced in the other array, as they are the same objects. However, changing a reference in one array will not affect the other.
TheBluMage
TheBluMage
Man, this is a great forum! There was only one reply when I started mine.[lol]
Woody FX
Woody FX
OK i think i get it!

So the two examples i posted above will have the exact same results even though i used 2 for statement to do it one by one.


What i should have done was

int array_1[][] = new int[8][8];int array_2[][] = new int[8][8];// populate both arrays with random datafor (int y=0; y<8; y++)     {     for (int x=0; x<8; x++)          {          int temp_holder = array_2[y][x];          array_1[y][x] = temp_holder;          }     } 


That would have copied only the values across from one array to the other without any complications.

andrewk3652
andrewk3652
Right.

What I meant (I'm actually from a C/C++ background myself as well) was actually that, whle Java's references are passed and handled similarly to pointers, we can't do the same operations with them as we could on C/C++ pointers.

So to me, they're not actually pointers. They're references. Pointers--, if you will. :-)
=========================Buildium. Codium. Fragium.http://www.aklabs.net/=========================
TheBluMage
TheBluMage
Quote:
Original post by Woody FX
That would have copied only the values across from one array to the other without any complications.

That'll work, but if you want to make it a little faster, use System.arraycopy on the inner arrays:

int array_1[][] = new int[8][8];int array_2[][] = new int[8][8];//do your stuff with array_1for(int i = 0; i < array_1.length; i++) {	System.arraycopy(array_1, 0, array_2, 0, array_1.length);}

arraycopy usually makes a bigger performance difference on larger arrays, so it won't matter too much for small arrays - up to you which method you use.
Woody FX
Woody FX
Thanks for all the help!

Using J2ME so arraycopy is not available.
CaptainJester
CaptainJester
Quote:
Original post by Woody FX
OK i think i get it!

So the two examples i posted above will have the exact same results even though i used 2 for statement to do it one by one.


Wrong. Your second method was correct. Once you dereference your arrays by filling in all subscript values, then it becomes a primitive type and only the values are copied.
int array1[][] = new int[8][8];int array2[][] = new int[8][8];//fill both arrays with random values//this will copy the reference for the entire array1 to array2//so they will remain identical until you change the referencearray2 = array1;//this will copy the reference for row 5 of array1 to row 5 array2//so they will remain identical until you change the reference//only changes to row 5 will affect both arraysarray2[5] = array1[5]//this will copy the integer value of 1 location from array2 to array1//not the reference//future changes to array2 will not affect array1array1[4][2] = array2[4][2];
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][
Zahlman
Zahlman
Quote:
Original post by Woody FX
Thanks for all the help!

Using J2ME so arraycopy is not available.


Yes, it is. It's not in MIDP, because that's not where the System class lives - it's in CLDC. [smile]

Anyway. My experience with Java tells me that "Java style" involves avoiding copying things. I rarely ever find that I want to clone objects in Java (J2ME or otherwise), but instead keep multiple references to the same one. Most of the time that you actually do need a separate object with its own state, it makes more sense to get one fresh from a constructor or factory method. (Of course, you could always make a factory method that clones an existing instance, if it *is* useful for your application :) )

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.