I'm setting an array equal to another array.
So let's say array B = array C.
Then, if I do operations on array B, changing it's values, does C also change?
I want to say absolutely not, but I'm having a brain fart and I feel like that what's happening in my code right now.
When you assign one array to another array the array will hold the reference so if you change the value in one array then it will surely change the value of other.
like in your example array B = array C. B will hold the reference to array C. so any changes in array B will reflect in array C.
Yes, they are changed.
The array is an object, so you assign only the reference, after assignment "array B = array C." both variables would hold the same reference. As a result you will have one object and two references
UPDATE
For "real copy" you need to use System.arraycopy() or Arrays.copyOf()
int[] arrayC = {1,2,3,4,5,6,7,8,9,10};
int[] arrayB = new int[arrayC.length];
System.arraycopy(arrayC, 0, arrayB, 0, arrayC.length );
Related
I have written 2-pieces of code to copy sub-array elements of a 2-D array as below
First Method:
String [][] actual = new String[5][5];
String [] arrayToCopy = {"1","2","3","4","5"};
actual[0] = arrayToCopy;
Second Method:
String [][] actual = new String[5][5];
String [] arrayToCopy = {"1","2","3","4","5"};
for(int i=0;i<5;i++)
actual[0][i] = arrayToCopy[i];
Is there any difference in functionality between above two methods as they are generating same output when I print the 2-D array?
One difference that you will need to worry about is that when you say
actual[0] = arrayToCopy;
You are actually not "copying" your array. Instead, you are replacing actual[0]
with a reference to arrayToCopy. If you change the array from either variable, the change will be reflected in the other. You can see it yourself:
System.out.println(actual[0][0]); // prints "1"
arrayToCopy[0] = "5";
System.out.println(actual[0][0]); // prints "5"
In the second approach, actual[0] and arrayToCopy reference different arrays, and you are actually "copying" elements from one array to the other. Changing one, will not change the other.
As for your question, does it differ in "functionality"? Depends on what you mean, but if the data is read-only then it's not that big of a deal. It only becomes a problem when you can modify the data and you're not careful and start changing things that shouldn't be changed.
In Java, assignments are by reference (except in primitive types (boolean, int, float, double, short, char, byte, long). When you do something like your first attempt, you don't copy the array, you are just referencing it in another variable.
actual[0] = arrayToCopy;
If you try doing something like that:
actual[0][3] = 5;
System.out.println(arrayToCopy[3]);
You will find 5. Any change happens to one, is reflected on the others.
But your second attempts copies the array.
If you want performant copying, consider using System.arrayCopy https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#arraycopy(java.lang.Object,%20int,%20java.lang.Object,%20int,%20int)
If you want performant programming and your array isn't shared between different objects, you could use the referencing solution (your first one).
But if you want to be in the safe side, or you worry about threading and data sharing between different objects, try copying.
I was trying to allocate an Integer array for 100 items, why this declaration isn't valid in Java?
Integer[100] intArr1; ----- (1)
Whereas this is valid:
Integer[] intArr; ----- (2)
As (2) is valid, how much memory does it occupy? Can anyone help to explain a bit.
There are some questions in SO which resemble my question, however they are not the same, and I did look in SO before asking this question.
The first one isn't valid because that's not proper Java syntax.
The second one occupies 0 memory, as you haven't created an array. Only a reference to an array, with the reference being null.
You need a new Integer[100] there to actually create the array object.
You are mixing two different things.
One thing is the type of variable. In your case, you want to say "the type of variable intArr is array of Integers", which is this code Integer[] intArr;
In variable, which type is array of Integers you can put any array of Integers you like, no matter the size, therefore you cannot pre-defined it.
The second thing is assign to a variable.
Integer[] intArr = new Integer[10];
To initialise an array with 100 items you write:
Integer intArr1[] = new Integer[100];
Your second line of code just declares a variable, there is no size declared.
When you declare an array, you don't give it a length. You only give it a length when you initialise it.
This is just a declaration:
int[] myArray;
If you want to initialize it with an array of length 100, you do this:
myArray = new int[100];
An uninitialised array is null by default, or inaccessible if it is in a local scope.
I came across 2 examples from my notes which is about copying arrays.
The first example given below, stated that it is not the way to copy an array. But, when i tried to run the code, it managed to copy all the values from array1 to array2.
int []array1={2,4,6,8,10};
int []array2=array1;
for(int x:array2){
System.out.println(x);
}
The second example given, was saying the right way to copy an array.
int[] firstArray = {5, 10, 15, 20, 25 };
int[] secondArray = new int[5];
for (int i = 0; i < firstArray.length; i++)
secondArray[i] = firstArray[i];
My question is, are these 2 examples appropriate to be applied in coding or Example 2 is preferred. If you were my lecturer, I were to apply Example 1.. I will be given less mark compared to Example 2 method or just the same?
The first example doesn't copy anything. It assigns a reference of the original array to a new variable (array2), so both variables (array1 and array2) refer to the same array object.
The second example actually creates a second array and copies the contents of the original array to it.
There are other easier ways of copying arrays. You can use Arrays.copyOf or System.arraycopy instead of explicitly copying the elements of the array via a for loop.
int[] secondArray = Arrays.copyOf (firstArray, firstArray.length);
or
int[] secondArray = new int[firstArray.length];
System.arraycopy(firstArray, 0, secondArray, 0, firstArray.length);
Perfect way to copy elements is
System.arraycopy(array1,0, array2, 0, array1.length);
That above code is replacement for you second example which avoids a for loop.
And where in your first example, you are just referring the first array. So what ever changes happened to the first array can be seen from second array.
My question is, are these 2 examples appropriate to be applied in coding or Example 2 is preferred.
See again, they are not doing the something to compare. First one pointing to array reference and second snippet of code referencing elements it it. So you just can't compare them.
And there are other ways to copy array elements as well just like others mentioned and I prefer System.arraycopy because
1)Arrays.copyOf creates another array object internally and returns it where as System.arraycopy uses the passed array.
2) Clone is the too slow. Never use it unless you have no other choice.
There are few reasons I'm avoid clone. Here is
Josh Bloch analysis on clone vs copy constructor (when you clone individual elements).
To demonstrate the problem with the first method, try this:
int[] array1 = {2, 4, 6, 8, 10};
int[] array2 = array1;
array1[0] = 0;
System.out.println(array2[0]);
What do you think this will print?
0
It will print 0, because array2 now points to array1:
both variables now refer to the same object,
so modifying the content of any one of these will appear to modify both.
So your first method is NOT called copying an array.
It's a simple assignment, from one variable to another,
in this case assigning the value of array1 to array2,
so that both variables point to the same thing.
As for your second method,
here's a much simpler way to accomplish the same thing:
int[] array2 = array1.clone();
In your first example, you end up with only one array with two variables referring to it. Assignment only passes a reference to the array. So both firstArray and secondArray are pointing to the same array. It's not a copy. Try to set firstArray[0] = 99 and print secondArray and you'll see it's the same array.
In the second example, it's an actual copy - you have created a new array and copied each value. Now, assigning firstArray[0] = 99 won't change the array referred to by secondArray because it's a copy.
So the answer is: if you give the first way, you'll get lower marks.
In real use, there are better ways to copy arrays, using System.arraycopy, Arrays.copyOf or firstArray.clone().
int[] secondArray = new int[5];
In the second example, you are creating an array of int using new operator and copying the elements to it manually using for loop. Whenever you use new operator in java, a new memory allocation happens (object creation).
Where as in the first, it is just reference assignment, both are pointing to same array. You can easily verify that by changing the content of one array see the same effect into the second array. This will not happen in the second array copying.
int []array2=array1;
for example: why this statement long[] n= new long[]; is wrong but this statement
long[][] n= new long[1][]; is right? How does the memory know how much memory needs to be assigned to the object in the second statement?
How does the memory know how much memory needs to be assigned to the object in the second statement?
Two things to remember here to figure out what's going on:
2D Java arrays aren't square, they're arrays of arrays.
You specify the size of an array when it's created.
So in this example, you're creating an array of longs (of size 1) to hold another array of longs - but you're not yet creating the second array (so you don't need to specify how large it will be.) In effect, the first array provides an empty "slot" (or slots if the outer array is longer than 1) for the inner array(s) to sit in - but the inner array(s) haven't yet been created, so their size doesn't need to be specified.
It doesn't just create an array of arbitrary length at all, it simply doesn't create any inner arrays.
You can perhaps see this more clearly if you try to access or store a long in the 2D array:
long[][] x = new long[2][];
x[0][0] = 7;
...will produce a NullPointerException (on the second line), because there is no inner array there to access.
In the first example that doesn't compile, you're trying to actually create an array of longs, but not giving it a dimension, hence the error.
when you write this - long[][] n= new long[1][];
you are creating array of arrays of long but you are not actually initializing those arrays right now
So if you do n[0] == null it will return true
that way you are free to initialize new array in any point of time later-
n[0] = new long[10];
So the point is - you need to provide size while initializing your array , that is why long[] n= new long[]; is wrong
If I've got float[] a = {1,2,3};, can I copy it using only float[] b = a; to obtain a deep copy? How do I know when I need to use a.clone()?
To clarify: I want to be able to change a (e.g. a[0]=4;) without affecting b.
Just making float[] b = a; is not enough because then the array object will be shared between the 2 references a and b.
But because you have an array of primitive types is enough to use float[] b = a.clone(). The clone in this case will make a deep copy and will duplicate the array object including the primitive values inside.
If you had an array of some reference type you would need to clone the array and than iterate and clone every object to get a deep copy.
Shallow copying means only making the new reference to point to the memory location of the old array, while deep copying means allocating a new memory location and copying the contents of the first array to other.
Use deep copy only when you are afraid that someone will nullify/delete the first array. In that case your second array will also be pointing to non existent memory or null. If you have a requirement to save the contents in the second array then go for deep copy otherwise use shallow copy.
Read more about shallow and deep copy here: http://en.wikipedia.org/wiki/Object_copy
This is how you can make shallow or deep copy of your array:
Shallow copy
float[] b = a;
Deep copy
float[] b = Arrays.copyOf(a);
float[] b = a; means you are assigning the reference of the Array object held by variable a to variable b.
Use Arrays.copyOf() or System.arraycopy() to clone an array in Java. Also look at the micro-benchmarking.
How do I know when I need to use a.clone()?
Whenever you write a = b in Java where a and b are not primitives (i.e. boolean, char, byte, int, long, float, double), you are copying a reference.
In your example, when writing float[] a = {1,2,3}; then float[] b = a;, you only create one array, but have two variables "pointing" to it. So any change made to the array will be reflected on a and b.
To get a deep copy of your array and achieve your goal, simply clone it:
float[] b = a.clone();
no you need to do it for example like:
float[] b = (float[])a.clone();
I don't think that you can clone primitives, but if you had to you could always create a new array and a loop to copy all the values of one into the other.