Calling function would update the array? - java

If I would send an array to some function, for example :
public void arrayManipulate(Someclass [] arr){
arr[0] = 2
}
for example (lets say it array of ints, even though I wrote someclass)
Someclass [] arr = new Someclass[15]
this.arrayManipulate(arr);
System.out.print(arr[0]);
what will it print? 0 as the deadult value in the array, or 2 (I want to know if calling that function would update the array or that should i return the array in that function and do arr = this.arrayManipulate(arr))
thanks in advance
George

If your code were to compile, and in both places the array were declared as int[], then the answer would be:
Yes, it will update the array. Although the arr object wouldn't have changed if reassigned in the arrayManipulate method, modifying an attribute/element inside it would be visible to the caller, because the updated object is the same.
So the number that would be printed is 2

Related

Return specific value from a 2D array

I'm trying to figure out a way to return the value from a specific position inside a 2D array in JAVA. I've been searching for hours. I might be tired, or using the wrong terms but I can't find anything useful so far...
So for example I have a variable "a" and I want it to receive the value that is contained at a specific array position.
So for example, I want the value contained at the position :
array[1][1]
To be saved into the variable "a". Any way to do this? Btw it's a 9x9 array so it contains 81 different value but I only need 1 specific value out of the array at a time.
Thanks in advance!
You just assign the value from the array as desired:
public class Foo {
public static void main(String[] args) {
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
int a = arr[1][1];
System.out.println(a);
}
}
// outputs : 5
Note that if a value hasn't been put in an array position then it will be in the uninitialized state. For an int this is 0.
int[][] arr = new int[9][9];
// all values in arr will be 0
Depending on the "Object type" you would assign using Object a = array[1][1]; and you can be more specific, as in int a = array[1][1];. GL

Shallow copying with primitives

From what I understand about Java (which is arguably pretty little =P), Java treats primitive values differently than objects. One example I can think of is that primitives are passed by value, while objects are passed via the value of their references.
Extending this, I have implemented code that creates an array of int, and shallow copied it over to a new array of int:
public class Test {
public static void main(String[] args){
int[] array = {2,3,4,5};
int[] copy = array;
copy[1] = 0;
for (int i : copy){
System.out.print(i);}
System.out.println();
for (int i : array){
System.out.print(i);}
}
}
However, the output is:
2045
2045
So, what puzzles me is why do both arrays change? I thought when we made a copy of the original array, we only copied over the values of the elements (since we are dealing with primitives)?
You didn't copy the array at all. What you did was make the references array and copy point to the same array in memory. Thus, when you change the array via one reference, the other reference will point to the same change.
Arrays are objects. When you set
int[] copy = array;
both copy and array refer to the same object. Your update
copy[1] = 0;
updates "both".
When you made the assignment copy[1] = 0, you told Java to take the array which copy refers to, go to position 1, and assign the value 0. Since you also have the following statement
int[] copy = array;
then copy and array refer to the same array in memory. You never really made a shallow copy, you only assigned another variable to point to the same array.
If you want to make a copy of the array, then you could try:
int[] copy = Arrays.copyOf(array, array.length);

Why Arryas.sort method sorts all other arrays that are linked to the one declared in the method? Java [duplicate]

This question already has answers here:
What is the difference between a variable, object, and reference? [duplicate]
(5 answers)
Closed 7 years ago.
Consider the following:
array1 contains a list.
int[] unSorted = array1; a new initialized array works as a (duplicate).
Arrays.sort(array1); suppose to sort only the original Array array1.
The problem occurs when I use the sort method Arrays.sort. It sorts all Arrays that are linked to array1, including the (duplicate)!! Why is that? It should change only the array that is declared inside the parentheses! Isn't it?
Your unSorted is not "a new initialized array". It is just a different name for the same array.
Arrays are Objects, not primitives. They are passed around as pointers, not as copies.
If you want a copy, use java.util.Arrays#copyOf.
Consider the following example: array & copy both refer to the same object - which is not the case with store.
import java.util.Arrays;
class Test {
public static void main(String[] args) {
// array & copy both refer to the same Object
double[] array = {5,4,3,2,1};
double[] copy = array;
// the following array is filled up "by hand" - thus it has no reference to the previous object
double[] store = new double[array.length];
for (int i = 0; i < array.length ; i++) {
store[i] = array[i];
}
Arrays.sort(array);
System.out.println("array"); // 1,2,3,4,5
for (double d: array)
System.out.println(d);
System.out.println("copy"); // 1,2,3,4,5
for (double d: copy)
System.out.println(d);
System.out.println("store"); // 5,4,3,2,1
for (double d: store)
System.out.println(d);
// Primitives show a different behaviour
double a = 5;
double b = a;
System.out.println(a + " / " + b); // 5 / 5
a = 10;
System.out.println(a + " / " + b); // 10 / 5
}
}
array1 isn't actually an array: it's a reference to an array. It's a bit like if you give someone a business card with your office address, that card isn't the actual office, but rather something that tells you how to reach the office.
When you do int[] unSorted = array1, you're making a copy of the reference, not the array. Again, it's like someone copying down the info on your business card.
And when you perform an operation on unSorted (like moving its elements to sort then), what you're actually doing is performing an operation on the object it points to. It's like saying, "go to the office specified on the business card called unSorted, and move the chair at desk 1 to desk 2."
If you then went to the office specified on the business card called array1, you would of course expect that the chair has moved there, since it's the same office.
If you want a copy, you have to create one. There are a few ways to do that, but the easiest is to use Arrays.copyOf.
Look at it this way :
You have a controller for a television (the array of course) and manage to duplicate the controller : you still have one television with multiple controllers.
If you change the television channel with one controller, even if you didn't touch the others, the televisions state has changed.
The same logic has to be applied to your problem.
Your unsorted variable is a reference.
Remember references point to an object.
So when you declared and instantiated array1, you may have done the following:
int[] array1 = new int[/*Any positive integer*/]
When declaring your unsorted reference variable, you did not instantiate a new array, you simply created a reference variable which points to the same object as array1.
Consider the image below:
So array1 and unSorted point to the same object, so of course if you call a method on either one of them you will effect the same object.
Because they are all the same array, not 'other arrays'.
You need to think about what you mean by 'all other arrays that are linked'.

Variable Arguments of Object passing in array inconsistency

I wrote a function that would take variable arguments as object.
When I passed in an array of ints of size 1 eg {9}, it treated args[0] as and int array[] than an int so the valueOf did not produce 9.
But If passed in and array of 2 or more ints eg {9,11} then it treated args[0] as 9 and args[1] as 11.
Why does it behave differently.
Note it is being written for Android.
protected String[] whereArgs(Object...args) {
String[] argsStrings = new String[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof String){
argsStrings[i] = (String)args[i];
} else {
argsStrings[i] = String.valueOf(args[i]);
}
}
return argsStrings;
}
EDIT Just had a look again I was actually passing them differently in the two ints scenario, one by one and not in an array, sorry.
Why doesn't it split the method(Object...args) into an array of objects when I pass in an array of ints, like what happens with method(int...args)
So now to get the string value I have to individually cast the type of array eg. for int[], double[]
if (args[0] instanceof int[]){
argsStrings[0] = String.valueOf(((int[])args[0])[0]);
Is there a way to write it for any type of object as this causes a crash
argsStrings[0] = String.valueOf(((Object[])args[0])[0]);
java.lang.ClassCastException: int[] cannot be cast to java.lang.Object[]
If you want to pass an array and treat each item as a separate item of the 'args' parameter of your method.. you need to cast your array to an Object[]. e.g: If you pass in your array of integers like below it will do what you want.
whereArgs((Object[])(new Integer[]{1, 2}))
The reason for this is when the source is compiled var-arg methods are actually replaced by an array. all places where the method is being called is converted to an array. If you want to pass an array so that each item becomes a separate argument.. then you need to use the correct array type. in your scenario this will be Object[]. This lets the compiler know that it can leave the method call as it is (without putting the arguments inside a new object[])

Working with an Array of Objects

#edit IT works, thanks for the answers:) I guess my bad was when I thought that
WORLD[i]=global.Values.CHUNKPATTERN();
simply takes the object on the right, clones its value('s), and assigns them to part on the left, while it turns out that it establishes a reference between two. Thanks again:)
I have simple begginer/newbie array problem:
for(int i=0; i<global.Values.WORLDVOLUME(); i++)
// global.Values.WORLDVOLUME() --> const, int. always the same.
{
WORLD[i]=global.Values.CHUNKPATTERN(); //to pre-define as 'zero only' object. Always the same. Const.
WORLD[i].chunknr=i+1;
}
System.out.println(WORLD[4].chunknr);
Of course I want WORLD[0] to have chunknr 1, WORLD[4] to have chunknr of 5 and so on.
Instead WORLD[i].chunknr=i+1; seems to update chunknr of ALL elements(not only WORLD[i]).
So that it looks like WORLD[0].chunknr = WORLD[1].chunknr=global.Values.WORLDVOLUME() here.
Anyone knows how to bypass that? I belive there's a simply solution...
Do I understand the array of objects correctly?
You can Have like(providing you have the class and constructor)
Point POINTARRAY[]= new Point[10];
POINTARRAY[1].x=5
POINTARRAY[1].y=6
POINTARRAY[3].x=17
POINTARRAY[3].y=1
Right?
How to assign that via loop?
Instead WORLD[i].chunknr=i+1; seems to update chunknr of ALL elements.
Are WORLD[0] and WORLD[1] different objects? They are not different if `WORLD[0] == WORLD[1] evaluates to true.
You have:
WORLD[i]=global.Values.CHUNKPATTERN();
Does CHUNKPATTERN create a new object every time it is called?
I bet this method
WORLD[i]=global.Values.CHUNKPATTERN();
always returns the same instance of an object so you have a reference to the same object in every slot of your array.
Subsequently
WORLD[i].chunknr=i+1;
you change the attribute chunknr of the same object in every iteration. You say
...seems to update chunknr of ALL elements
kind of true, because all elements reference the same instance.
You need to find a way to have global.Values.CHUNKPATTERN(); return a new object every time.
This line is your problem:
WORLD[i]=global.Values.CHUNKPATTERN();
This is assigning WORLD[i] a reference to global.Values.CHUNKPATTERN(), meaning that they both point to the same object! And for each iteration of your loop you are just creating more and more references to the same global object.
Sometimes this isn't what you want. In this case you need to copy the value, which can be done in a number of ways, but in most cases you can simple clone it. All Java objects support a clone() method, although sometimes you need to override it to do the correct thing for your class.
All this means is that you should replace the above line with:
WORLD[i]=(YourType)global.Values.CHUNKPATTERN().clone();
where YourType is the actual type of the class, since you omitted that from the code snippet you posted.
Hope that helps!
I guess the following line returns always the same reference:
global.Values.CHUNKPATTERN();
so the different array indices are actually point to the same referece. It's only a guess because you didn't tell us how the above function works.
Here's an example of what different array element could point to the same instace:
public class AClass{
public int val = 0;
}
AClass[] array = new AClass[2];
AClass classInstance = new AClass();
array[0] = classInstance;
array[1] = classInstance;
The code above instatiated a single AClass object (classInstance), but use 2 different array elements to reference the same instance:
System.out.println("array 1 value " + array[1].val ); // both element initialized to 0 so it prints 0
array[0].val = 15; // actually is classInstance.val to be modified, through the reference to it stored inside the first element of the array.
System.out.println("array 1 value " + array[1].val ); // print 15
For what concern the POINT example, you can use for loop this way:
Point POINTARRAY[]= new Point[10];
for(int i = 0 ; i < POINTARRAY.length; ++i)
{
POINTARRAY[1].x=...;
POINTARRAY[1].y=...;
}

Categories