Arrays and Referencing [duplicate] - java

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
Consider the following code:
public static void resize(int[] x){
x = new int[x.length*2];
System.out.println(x.length + " ");
}
public static void main(String[] args){
int[] x = {1,2};
resize(x);
System.out.println(x.length);
}
The output is "4 2". The question is: I thought that when we are defining an array in the code of the new length, the other array (the previous one with length 2) would be discarded, as now the value of the array points to the "larger" array. So, why would then print out at the end as length 2? I used Arrays.toString to verify, and indeed, the actual values of the array after the void method are {1,2}. This is confusing, as I thought that the array itself would be changed as the value is a pointer to the memory address (in contrast with using the method on a char/int variable, which would not affect the value of the variable).

When you call resize, you pass an array object to the method. This is the basic flow of your program:
initialize array of size 2
pass that array to resize()
resize has a reference to the value of the array
resize points it's reference to a new array twice the size of the old reference
prints "4"
main() prints the size of the initial array "2"
You don't change the original array in the new method, it merely has an array of the same value.

Because Java passes by value, the array doesn't change after your call to resize. (I'm assuming the output is actually 4 2, not 2 4.)
If you want resize to effect a permanent change, you should have the method return x; as its final statement (or use a global variable):
public static int[] resize(int[] x){
x = new int[x.length*2];
System.out.println(x.length + " ");
return x;
}
public static void main(String[] args){
int[] x = {1,2};
x = resize(x);
System.out.println(x.length);
}

The scope of your x variable in resize
public static void resize(int[] x){
x = new int[x.length*2];
}
is local to that function. It does not affect the x that was passed in. This means that as soon as resize completes, that local copy disappears and is eventually garbage collected.
If you want to resize the original array, return it. For example:
public static int[] getNewArrayOfDoubleLength(int orig_length){
return new int[orig_length * 2];
}
And call it with
x = getNewArrayOfDoubleLength(x.length);
Since arrays are immutable, this is a new array. The original one still exists (although it's inaccessible) until it's garbage collected.

Related

Why is the following Output the right one? [duplicate]

This question already has answers here:
Assigning Array to new variable, changing original changes the new one
(4 answers)
Problem with assigning an array to other array in Java
(4 answers)
How can an integer array be a reference type?
(2 answers)
Closed last month.
public class Alle {
public static void main(String[] args) {
int[] arr = {1,2,3,4};
int [] y = arr;
y[0] = 15;
System.out.println(Arrays.toString(arr));
}
}
The Output is 15,2,3,4 but why? I never changed "arr".
In Java, arrays are objects, not primitive types. When you are assigning link to arr to the new variable, y still points to arr, so you are actually changing arr. Thats it. But if you want to copy the array, you can use this method: Arrays.copyOf(int[] original, int newLength)
Let's assume you have a son, named jackson.
You introduce him to your friend, "Hey Friend, meet my son Jackson".
The friend says, "Hi Jackson, I'll call you jake."
Later that friend calls him and says, "Hey Jake, here take a handful of candies".
your son Jackson comes to you, and you see he has a handful of candies.
But how ? You never gave jackson candies. But your friend gave to jake.
Makes sense ?
In your code, the arr, and the y are exactly the same entity, not equal, not copy, but the exact same Object. So you make changes at one place, it'll show at the other one as well.
When you initialized the integer array viz arr in your case, it allocated a space in the heap to your reference variable arr when you executed the following code:
int[] arr = {1,2,3,4};
This arr is referring to an integer array in heap as arrays are objects in java.
Now when you performed the following code:
int [] y = arr;
This created one more reference variable y which is referring to the same object in the heap that your reference variable arr was referring to, that is why whatever changes you make through your reference variable y or reference variable arr will reflect the changes of the object created in the heap as they are referring to the same object.
If you want a new object allocated to your reference variable y that resembles the elements of your arr array then you can clone it. The following code represents it:
public class Alle {
public static void main(String[] args) {
int[] arr = {1,2,3,4};
int [] y = arr.clone(); //change here
y[0] = 15;
System.out.println(Arrays.toString(arr));
}
}
This gives an output:
[1, 2, 3, 4]
Hence your arr array is not affected this time.

How is the first line of output generated? [duplicate]

This question already has answers here:
Overloaded method selection based on the parameter's real type
(7 answers)
Closed 6 years ago.
The following code showed up in a past paper with multiple mistakes (which i have spotted and fixed easily) but what i struggle to understand is the output.
The classes:
import java.util.*;
class Count {
int i, s, o, l, c;
public Count(Object[] objects){
for(int j=0; j<objects.length; j++){
count(objects[j]);
}
}
public void count(Collection x){c++;}
public void count(List x){l++;}
public void count(Double x){i++;}
public void count(Object x){o++;}
public void count(String x){s++;}
public String toString(){
return c + ", " + l + ", " + i + ", " + o + ", " + s;
}
}
import java.util.LinkedList;
public class Test {
static Object[] objects = {new Double(10), new String("Q1"),
new Object(), new LinkedList()};
public static void main(String args[]){
System.out.println(new Count(objects));
for(Object o : objects)
System.out.println(o);
}
}
Generated output:
0, 0, 0, 4, 0
10.0
Q1
java.lang.Object#6d06d69c
[]
I'd appreciate if someone could explain the output with reference to the code.
Side note: the first line of output is what puzzles me. The other bit i understand.
Last note: This is a unique question regarding the output. It is not a duplicate of any question (to the best of my knowledge - the link to the 'possible duplicate' is regarding method overloading not "how is this output produced?" and the outcomes in both questions are unique to each other) so a precise answer would be helpful. Thanks.
for(int j=0; j<objects.length; j++){
count(objects[j]);
}
corresponds to
public void count(Object x){o++;} only
because the argument you're passing when you call count(objects[j]) is an object. You're calling a count function which has an object as parameter, and that's what Java is doing for you.
The number of objects in objects[] is 4. Hence count(Object x) gets called 4 times.
As regards the other integers, they are initialized by default to 0, and hence you see 0.
That's why you see 0 for all variables except o.
public Count(Object[] objects){
for(int j=0; j<objects.length; j++){
count(objects[j]);
}
In these lines you're creating an array of elements in which each element is of type Object itself (it's the class from which every other class inherits). So output of counting objects of type Object in array shouldn't be a surprise.
(Counting is held by overloaded methods. When you call counting function the one that is chosen must have the most suitable type. Hence, counting with Object type as a parameter is picked.)
0, 0, 0, 4, 0
Next, you're creating new array of Objects, initializing each element of the array with different type.
static Object[] objects = {new Double(10), new String("Q1"),
new Object(), new LinkedList()};
It's possible because of upcasting. As I mentioned before, every element inherits from Object class, so every object in your program is in fact Object. Using mechanism of polymorphism you're program can now "deduce" the real type of elements in your array. Namely, you can see it here
for(Object o : objects)
System.out.println(o);
where Java is printing information obtained dynamically. Hence, double is printed as double, string as string, object itself doesn't have more sensible toString() method than printing its inner "name"(by the way this is the field each object of type Object has) and of course empty link list is no more than [].
One of your problems lies here:
public void count(Collection x){c++;} // never called, init to 0
public void count(List x){l++;} // never called, init to 0
public void count(Double x){i++;} // never called, init to 0
public void count(Object x){o++;} // called 4 times, result is 4
public void count(String x){s++;} // never called, init to 0
You never initialize any of the variables (c, k, i, o, s) so I believe the int type is auto initialized to 0. Then the next time it is called it will increment. So end result is:
0, 0, 0, 4, 0 //
Now the rest:
10.0 // 10.0 because that was value specified when Double was created
Q1 // Q1 because that was the String value when it was created.
java.lang.Object#6d06d69c // memory address of where Object is
[] // initialized to empty list []
The first line outputs the number of Collections, Lists, Doubles, Objects, Strings passed to the constructor of the Count instance in the main method of the Test class, since all of the Count classes only accept one parameter and the count variables are not static four of these will always be zero.
The next four lines print the four objects in the static objects array. This is effectively just printing the results of each objects toSrting() method.

Confusion in passing an object to a function [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
while learning C language I have learned that when you pass a variable to a function. you are not passing the variable itself you are passing a copy of it so the actual varible's value will not change unless the function returns a value and you assign that value to the variable.
but I just executed this program and this happened when I passed "Newobj" object to a "changer" function and then change the values of the variables and then print the new variables values it is working. It should not happen right? because I am sending the copy of "Newobj" to "copyobj". explain please I am confused.
Note: Explain in detail please. My brain is slow. I know the concepts of c and few concepts of c++;
here is my code:
public class PassObjects {
int regno;
String name;
double per;
PassObjects(int a,String s,double p){
regno=a;
name=s;
per=p;
}
PassObjects changer (PassObjects copyobj){
copyobj.regno=797;
copyobj.name="Srimanth";
copyobj.per=70.9;
return copyobj;
}
public static void main(String[] args){
PassObjects Newobj= new PassObjects(86,"srimanth",85.4);
System.out.println("The original values of Instance variables are "+Newobj.regno+" "+Newobj.name+" "+Newobj.per);
Newobj.changer(Newobj);
System.out.println("The changeed values of Newobj are "+Newobj.regno+" "+Newobj.name+" "+Newobj.per);
}
}
output is here:
The original values of Instance variables are 86 srimanth 85.4
The changeed values of Newobj are 797 Srimanth 70.9
What you are doing is passing a pointer to an object. You are effectively modifying the PassObjects object.
There is a difference between a reference type and a value type. For example, a function that takes an integer and modifies it will indeed receive a copy of that integer.
public void add(int x)
{
x = x + 1;
}
However, an array of ints is also a reference type.
When you call this function using the following code:
int x = 5;
add(x);
// X will still have a value of 5.
This is because x is a value-type. You call the function and pass in a copy of the integer.
However, when you create an object, you do not pass a copy of the entire object. See code below.
public void ChangeName(SomeObject x, String newname)
{
x.name = newname;
}
SomeObject x = new SomeObject("thename");
ChangeNameTo(x, "newname"); // As the comment below pointed out, you don't even have to reassign.
//x.name will have the value "newname" now.
You can read more here and here.
Java does manipulate objects by reference, and all object variables are references.
That means u only created a new reference to the same object and when u changed the values then it gets changed in actual object.

If Java is pass by value, how does this swap method work? [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
OK so I understand that Java is pass by value (including for References, it passes the Object by the VALUE of the reference - i.e. the address).
If so then why does the swap(int[] array) method - passing an array of primitives - work?
public class TestArraySwap {
public static void swap(int a, int b) {
int temp =b;
b=a;
a=temp;
}
public static void swap(int[]a) {
int temp = a[1];
a[1]=a[0];
a[0]=temp;
}
public static void main(String[] args) {
//Test Primitive swap
int a=1;
int b=2;
System.out.println("a="+a +" b="+b);
swap(a,b);
System.out.println("a="+a +" b="+b);
//Test array swap
int[] array = new int[2];
array[0]=1;
array[1]=2;
System.out.println("a[0]="+array[0] +" a[1]="+array[1]);
swap(array);
System.out.println("a[0]="+array[0] +" a[1]="+array[1]);
}
}
The output is
a=1 b=2
a=1 b=2
a[0]=1 a[1]=2
a[0]=2 a[1]=1
The second swap works - I would expect it not to but perhaps I am missing something?
The main method has a reference to an array:
R1 ------> [1, 2]
Then it calls the swap() method. So a copy of the reference to the same array is created and used by the swap() method:
R1 -----> [1, 2]
^
|
R2 ---------|
Then the swap() method changes the content of the array:
R1 -----> [2, 1]
^
|
R2 ---------|
And it returns. R1 still references the same array, whose content has been changed.
After some more searching I found this answer
Array seems to be getting passed by reference in Java, how is this possible?
and of course the Java spec itself
In the Java programming language, arrays are objects
Everything in Java is passed by value (by copy).
swap(int[] a) works, because it passes (copies) only an address of the beginning of an array. Later it directly modifies memory under that address (a[0]) and the next one (a[1]).
swap(int a, int b) doesn't work, because it modifies copies of integers.
References in Java are something pointing to an object in heap. Arrays in Java are always allocated in heap. So arrays in Java are like normal objects.
References to objects in Java are stored in stack like primitive variables (int, long), it's a memory address stored in variable. So when they say that objects are passed by value, the literal meaning is that you copy address value into method parameters.
And for me this has always been confusing because though I do understand the process, I can't recall how it's properly named as
there are no references in Java
I'm always stuck when I hear the word 'value' applied to an object
The swap works because you pass the address (reference) of the array to the method. The method then operates on that array -- the same one the other method has a reference to.
I really don't like the statement, "Java is pass by value." I think it's really confusing.
public void methodA(){
int[] values = {1,2};
// MethodA stack frame has a register that contains a
// memory address (let's say it's 0x1F) that points to a contiguous section of
// memory sized for an integerarray of size 2.
methodB(values); // Pass the **memory address** (aka REFERENCE) not the register address
System.out.println(values[0]); // Prints "100"
}
public void methodB(int[] ints){
// MethodB stack frame now has a register with the memory address (0x1F)
// of 'ints' which is the same address that MethodA stack frame has.
// The same REFERENCE
ints[0] = 100; // Alter the value in mem of 0x1F+0
ints = new int[2]; // The local register overwrites the memory address of
// the REFERENCE value that was there with
// a new memory address -- say 0x5A
// since it's not storing it in the same register
// as MethodA, MethodA will not reflect this.
}

Array and methods?

I'm doing a task for a course in Java programming and I'm not sure how the following thing is working? The method below takes the value from an array and a integer. The integer should be added to the array and then be used outside the method in other methods and so on, but how could this work when the method has no return for the new content of the array? There is a void in the method? Have I missed something? Preciate some help? Is there something about pointers?
public static void makeTransaction(int[] trans, int amount);
Arrays in Java are objects. If you modify the trans array inside the method, the changes will be reflected outside of it1. Eg:
public static void modify(int[] arr)
{
arr[0] = 10;
}
public static void main(...)
{
int x = {1, 2, 3};
System.out.println(x[0]); // prints 1
modify(x);
System.out.println(x[0]); // now it prints 10
}
Note that native arrays can't be dynamically resized in Java. You will have to use something like ArrayList if you need to do that. Alternatively you can change the return type to int[] and return a new array with the new element "appended" to the old array:
public static int[] makeTransaction(int[] trans, int amount)
{
int[] new_trans = Arrays.copyOf(trans, trans.length + 1);
new_trans[trans.length] = amount;
return new_trans;
}
1 It is also worth noting that as objects, array references are passed by value, so the following code has no effect whatsoever outside of the method:
public void no_change(int[] arr)
{
arr = new int[arr.length];
}
You can't add anything to an array. Java arrays have a fixed length. So indeed, what you want to do is impossible. You might make the method return an int[] array, but it would be a whole new array, containing all the elements of the initial one + the amount passed as argument.
If you want to add something to an array-like structure, use an ArrayList<Integer>.
Do you have to keep the method signature as is?
Also, can you be a bit more specific. When you say "the integer should be added to the array", are you referring to the amount argument? If so, then how is that amount added? Do we place it somewhere in the array or is it placed at the end, thus extending the array's length?
As far as pointers go, Java's pointers are implicit, so if you don't have a strong enough knowledge of the language, then it might not be so clear to you. Anyways, I believe that Java methods usually will pass objects by reference, and primitives by value. But, even that isn't entirely true. If you were to assign your object argument to new object, when the method terminates, the variable that you passed to the method is the same after the method executed as it was before. But, if you were to change the argument's member attributes, then when the method terminated those attributes values will be the same as they were inside of the method.
Anyways, back to your question, I believe that will work because an array is an object. So, if you were to do the following:
public static void makeTransaction(int[] trans, int amount)
{
trans[0] = amount;
}
// static int i;
/**
* #param args
*/
public static void main(String[] args)
{
int[] trans = {0,1,3};
makeTransaction(trans, 10);
for(int i = 0; i<trans.length; i++)
{
System.out.println(trans[i]);
}
}
The output of the array will be:
10
1
3
But, watch this. What if I decided to implement makeTransaction like so:
public static void makeTransaction(int[] trans, int amount)
{
trans[0] = amount;
trans = new int[3];
}
What do you think that the output will be? Will it be set to all zero's or will be the same as it was before? The answer is that the output will be the same as it was before. This ties in to what I was saying earlier.
I might've assigned that pointer to a new object in memory, but your copy of the pointer inside of the main method remains the same. It still points to the same place in memory as it did before. When the makeTransaction method terminates, the new int[3] object that I created inside of it is available for garbage collection. The original array remains intact. So, when people say that Java passes objects by reference, it's really more like passing objects' references by value.

Categories