Calling methods with array output twice in same scope - java

Suppose you have a method that outputs arrays of different sizes.
Before you use it, you need to create an array reference variable. Before you can do that, you need to find the array length, e.g.
int[] intArray = new int[methodReturnsArray().length]
And then you can set intArray to your array produced by methodReturnsArray().
I feel a bit uneasy about this, because we're calling methodReturnsArray() twice: once to find out how big the array is, and again to set it equal to the reference variable.
Is that wasting resources to call the method twice, or is the array only created once (when you find its size)?
Edit: I know you can just initialize intArray to the method returned by the array. But for some complicated reasons (to do with "methodReturnsArray" being called in a loop with a different-sized array for each iteration) I need to know whether calling twice will waste computational resources.

It depends on how you will then fill new array variable.
But the common approach will be introducing new local variable for saving reference to original array from method methodReturnsArray. i.e.:
int[] methodArray = methodReturnsArray();
int[] intArray = new int[methodArray.length];
...
Then the best way for copying an array is System.arrayCopy(...) method.
This approach will work in any case, and it will prevent you from doing things in method methodReturnsArray twice.

Related

Is there any functional difference between direct sub array copy into 2-D array and using for loop in java

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.

Why `Integer[100] arr;` is invalid, while `Ineger[] arr;` is valid?

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.

Array of custom classes changing when a different array of classes updated java [duplicate]

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;

JAVA gui: array being modified unexpectedly

Problem with gui application where array of objects been passed to the constructor, however when new round is initialised, it modifies somehow const_AnimalFamily array, where I want to make it unchanged at each round, however final cannot be used here. Other class initialises this class, however here is my main. Any suggestions? Thank you!
why its been changed each time I modify animalFamily, const_AnimalFamily being affected even if I did not do anything to it?
Your code is much too large for being analyzed. But as you declared two arrays assigning their references to fields, I simply assume that you once assign one field to the other.
And indeed you have the line:
animalFamily = const_AnimalFamily;
I futher assume that you want to copy all contents from const_AnimalFamily to animalFamily. But this is not the case.
In Java, such assignments simply assign the reference to the variable (or the field). That means, both fields now refer to the same array. Actually, the array that was referred to by the field const_AnimalFamily before, is now obsolete and cannot be used anymore.
If you now access some array content, for example
animalFamily[0] = ...
and afterards read from
... = const_AnimalFamily[0]
you will get the same object that you previously wrote into the array.
Solution: If you really wanted to copy the array, do the following:
animalFamily = Arrays.copyOf(const_AnimalFamily, const_AnimalFamily.length);
Another (better) solution would be to use collections.
It's right as per your observation "Problem with gui application where array of objects been passed to the constructor, however when new round is initialised, it modifies somehow const_AnimalFamily array, where I want to make it unchanged at each round".
See this your code:
public AnimalGUI(Animal[] temp) {
System.out.println("INSIDE CONSTRUCTOR");
const_AnimalFamily = temp;
You are changing the reference of const_AnimalFamily to temp. So now whenever you modify temp (from wherever it was passed) you are going to go through same changes in your constant array.
I would suggest you do something like:
You do a deep copy of your temp array rather than changing the reference.
OR
when you pass temp array, you pass the cloned (Arrays.copyOf) version of array rather than raw array.

Behavior of an array after sorting in Java

I want to get some views on the behavior of the following program :
package main;
import java.util.Arrays;
public class StringAnagram {
public static void main(String args[]) {
String a = "aabbaabb";
char[] aArr = a.toCharArray();
Arrays.sort(aArr); //1
Arrays.sort(a.toCharArray()); //2
System.out.println(aArr); // Sorted
System.out.println(a.toCharArray()); // UnSorted
}
}
According to me statement 1 sorts the character array referenced by aArr but when it comes to statement 2 the sorting of character array is taking place but somehow the sorted array is not referenced by any variable, so the behavior is lost. Could someone please help me with the same.
Yes. You are right.
Each call to toCharArray() actually creates a new array instance with the characters in the string.
In the case of aArr, you actually refer to the new array instance, you use aArr to sort. Its the array instances referred by the variable aArr which gets sorted.
But when you pass a.toCharArray() to Array.sort() method, you are passing array instance which you don't have a variable referring to. The array instance gets sorted but you don't have any reference.
When you you call println using a.toCharArray() again a new array instance is created and passed to println which is obviously unsorted.
Well, let's see what happens.
First, a.toCharArray() is called. This returns a new char array containing the chars "aabbaabb".
Then, this array is sorted.
You didn't give yourself a way to access the array, so you can't. This is what "lost" means here. Nothing special or magic happened, you just made an array you can't access. It's not going to waste memory - the garbage collector will detect that it can't be accessed, and destroy it.
It's similar to if you just did this without the sorting:
a.toCharArray();
Again, toCharArray goes and makes an array for you, and you don't give yourself a way to use it, so it's also "lost". The sorting was a red herring.
Arrays.sort(a.toCharArray());
This sorts the array returned by a.toCharArray() and not the String a. So whenever you do a.toCharArray() you get a separate(new) Character array of the String. Hence it is unsorted.

Categories

Resources