I am facing a weird problem in the following piece of code:
public class Main {
public static void main(String args[]){
int[] c = {0};
int[] a = c;
int[] b = c;
a[0] = 1;
b[0] = 2*a[0];
System.out.println(" a " + a[0]);
}
}
This returns "a 2", and not "a 1", which means that the value of the array a changed, even though the operation is only supposed to affect the array b!
Does anyone know where this might come from, and how to solve it please?
The culprit is here:
int[] c = {0};
int[] a = c;
int[] b = c;
You think you're creating three different arrays but really they're all pointing to the same array c.
System.out.println(a + "-" + b + "-" + c); //[I#1b6d3586-[I#1b6d3586-[I#1b6d3586
All variables are actually pointing at the same array in memory.
What you have done is effectively create 2 copies of the same array as when you declare an array:
int[] a = c;
This is the same as writing:
int* a = c;
Writing, c is the same as &c[0], its the base address of the array.
So:
int[] c = {0};
int[] a = c;
int[] b = c;
a[0] = 1; // This also sets the value of c[0] and b[0] to 1
b[0] = 2*a[0]; // This is 2 * 1 = 2
Related
This question already has answers here:
Are arrays in java pass by reference or pass by value?
(3 answers)
Closed 2 years ago.
I am trying to merge to arrays nums1 and nums2...
m = size of filled elements in nums1
n = size of nums2
An array is passed by reference in a method...So if any change occur inside a method, it will reflect outside it...So then I assign nums1 = result inside merge method...it's showing inside the the merge method, when I print the nums1 array by below code:
System.out.println("Result: " + Arrays.toString(nums1));
..So the nums1 array will now point towards "result" array..
but when I try to print the same inside the "main" method by the code below:
System.out.println("Merged Array: " + Arrays.toString(nums1));
Then it's not showing the desired result.i.e nums1 should show the "result array values" as change din the "merge" method..
Please someone explain why this is happening?
My entire code of merging the two arrays is as below:
public class MergeSortedArray {
public static void main(String[] args) {
int[] nums1 = {1, 2, 3, 0, 0, 0}, nums2 = {2, 5, 6};
int m = 3, n = 3;
System.out.println("Original Array: nums1: " + Arrays.toString(nums1));
System.out.println("Original Array: nums2: " + Arrays.toString(nums2) + "\n");
merge(nums1, m, nums2, n);
System.out.println("Merged Array: " + Arrays.toString(nums1));
}
public static void merge(int[] nums1, int m, int[] nums2, int n) {
int n1idx = 0, n2idx = 0;
int[] result = new int[nums1.length];
int ridx = 0;
while(n1idx < m && n2idx < n) {
if(nums1[n1idx] < nums2[n2idx]) {
result[ridx++] = nums1[n1idx++];
} else {
result[ridx++] = nums2[n2idx++];
}
}
// fill the remaining elements from nums1
while(n1idx < m) {
result[ridx++] = nums1[n1idx++];
}
// fill the remaining elements from nums2
while(n2idx < n) {
result[ridx++]= nums2[n2idx++];
}
nums1 = result;
System.out.println("Result: " + Arrays.toString(nums1));
}
}
When you assign result to nums1, it does not change the reference in the called program. It is of local significance only. This is because the actual reference is passed by value and you can't change that with a simple assignment.
However, any changes you make to nums1 contents in the merge method will be reflected in the calling program since you are changing what the reference refers too and not the reference itself.
Everything in Java is passed by value. Even arrays and objects.
Here is an example. The Identityhash shows a value indicative of the reference. Note that after the last assignment in the method, the passed reference was not changed.
public static void main(String[] args) {
int[] q = {4,5,6};
System.out.println("q in main = " + System.identityHashCode(q));
callMethod(q);
System.out.println("q in main = " + System.identityHashCode(q)); // hasn't changed
}
public static void callMethod(int[] v) {
System.out.println("v in method = " + System.identityHashCode(v));
int[] otherArray = new int[]{1,2,3};
v = otherArray;
System.out.println("v in method after assignment = " + System.identityHashCode(v));
}
Prints
q in main = 925858445
v in method = 925858445
v in method after assignment = 798154996
q in main = 925858445
I am writing a program here that takes two int[] arrays and subtracts each element from each other and stores the result in a new array.
this sounds pretty sound and i know my math is right seeing as its simple subtraction..
my method is here,
public int[] diff(int[] nums1, int[] nums2)
{
int[] diffArray = new int [nums1.length];
int tempValue = 0;
int tempValue2 = 0;
int subtract = 0;
if (nums1.length != nums2.length)
{
diffArray = new int[0];
}
else
{
for (int i = 0; i < nums1.length && i < nums2.length; ++i)
{
tempValue = nums1[i];
tempValue2 = nums2[i];
System.out.println("temp value 1: " + tempValue); //just me trying to debug
System.out.println("temp value 2: " + tempValue2); //just me trying to debug
subtract = tempValue2 - tempValue;
System.out.println("Subtracted :" + subtract); //just me trying to debug
diffArray[i] = subtract;
}
}
return diffArray;
}
to test this i wrote a couple small pieces of code in my driver class.
The problem is, i made those 3 debug print statements in my for loop to see if i had the right numbers and everything is correct it just seems like its not storing it in diffArray?
for example,
//Array of 1 element each : r(0)
givenArray = new int[] {4};
givenArray2 = new int[] {4};
diffValue = srvObj.diff(givenArray, givenArray2);
result = (diffValue == new int[] {0}) ? PASS : FAIL;
System.out.println(testNum + ": " + result);
++testNum;
//Array of multi-elements each that are diff : r({6, 10, 37})
givenArray = new int[] {4, 5, 3};
givenArray2 = new int[] {10, 15, 30};
diffValue = srvObj.diff(givenArray, givenArray2);
result = (diffValue == new int[] {6, 10, 37}) ? PASS : FAIL;
System.out.println(testNum + ": " + result);
++testNum;
note : i am subtracting array2 from array1 not the other way.
however i keep getting FAIL every time? i can see in my print statements its done the math for each element
Surely there must be a problem when i try to give diffArray[i] the resulted subtraction?
You are checking for array equality incorrectly here (and your other tests):
result = (diffValue == new int[] {0}) ? PASS : FAIL;
In Java the == operator checks for reference equality when applied to objects, and the new array you create in this statement will never be the same object as diffValue.
What you need to do is to use the equals() method in the Arrays class, which checks for value equality.
A quick example:
int[] arr1 = { 0 };
int[] arr2 = { 0 };
System.out.println(arr1 == arr2); // false
System.out.println(Arrays.equals(arr1, arr2)); // true
In Java (and a lot of other languages), arrays are objects, so == won't work to compare them. It compares the references, so it checks if they're the same object, not whether they contain the same elements:
int[] a = new int[] {1,2,3};
a == a; //true
int[] b = new int[] {1,2,3};
a == b; //false
There's a method, though, Arrays.equals(), that can compare them:
result = Arrays.equals(diffValue, new int[] {0}) ? PASS : FAIL;
You need to import Arrays at the beginning of your program, though:
import java.util.Arrays;
It looks like your diff() is working, though.
Your test condition is wrong - diffValue == new int[] {6, 10, 37} will always resolve to false because the Java equality operator checks that the two variables are REALLY the same thing, not simply equivalent. Please see Comparing two integer arrays in java for ideas on comparing int arrays.
This question about a 2D array being passed into a method came up in class. Can someone explain why the original array d is unchanged after a call to doStuff() ? I debugged the code and saw that the method was reversing the values, but then when returned, the original array remained unchanged. I thought passing arrays into a method and changing values in that method would affect the original array. Here that is not the case, the original array is unchanged. My first thought was the orignal would be reversed. But no.
Initialize the array d and call doStuff as
follows:
int d[][] = { {-1,0,1},
{5,6,7},
{2,3,4} };
doStuff(d);
public static void doStuff (int [][] frst)
{
int len = frst.length;
int sec[][] = new int[len] [];
for (int j=0; j<len; j++)
{
sec[j] = frst[len –j -1];
}
frst = sec;
}
You already have some good answers, but here's a bit of code showing the two cases that may seem to be inconsistent, but are indeed explained by the fact that java is pass-by-value. The tricky bit is that in the case of arrays, it's the reference to the array that's being passed by value, not the array itself.
Hence the called function receives a copy of the reference to the same array as the caller function, and can modify elements within that array. But when the called function modifies the reference itself to refer to a different array it is modifying a copy, which has no effect on the caller --- that is, in the caller environment the variable is still referring to the original array.
This is easier to explain with boxes and arrows :-), but hopefully the code and output below will be helpful:
$ cat PBV.java
class PBV
{
private static void modfiyArrayElement(int[] intArray) {
// intArray is referring to the same array as in main
intArray[0] = 17;
}
public static void main(String[] args) {
int[] a = new int[]{ 1, 2, 3 };
System.out.println(a[0]);
modifyArrayElement(a);
System.out.println(a[0]);
}
}
$ java PBV
1
17
$ cat PBV2.java
class PBV2
{
private static void modfiyArrayReference(int[] intArray) {
System.out.println("\nIn modifyArrayReference:");
System.out.println("intArray[0] is " + intArray[0]);
System.out.println("ref value of intArray is: " + intArray);
intArray = new int[] { 100, 200, 300 };
// intArray is no longer referring to the same array as in main!
// at this point munging with intArray won't have an effect in main
System.out.println("\nintArray[0] is now " + intArray[0]);
System.out.println("ref value of intArray is: " + intArray +"\n");
}
public static void main(String[] args) {
System.out.println("in main:");
int[] a = new int[]{ 1, 2, 3 };
System.out.println("a[0] is " + a[0]);
System.out.println("ref value of a is: " + a);
modfiyArrayReference(a);
System.out.println("back in main:");
System.out.println("a[0] is still " + a[0]);
System.out.println("ref value of a is still: " + a);
}
}
$ java PBV2
in main:
a[0] is 1
ref value of a is: [I#55a6c368
In modifyArrayReference:
intArray[0] is 1
ref value of intArray is: [I#55a6c368
intArray[0] is now 100
ref value of intArray is: [I#37670cc6
back in main:
a[0] is still 1
ref value of a is still: [I#55a6c368
Java is pass by value
Return your value and set it to your value.
int d[][] = { {-1,0,1},
{5,6,7},
{2,3,4} };
d = doStuff(d);
public static int[][] doStuff (int [][] frst)
{
int len = frst.length;
int sec[][] = new int[len] [];
for(int j=0; j<len; j++)
sec[j] = frst[len-j-1];
return sec;
}
}
You can also set the value of the passed array directly (array variables are a reference to an array, so editing the elements of your passed array reference will work:
public static void doStuff (int [][] frst)
{
int len = frst.length;
int sec[][] = new int[len] [];
for(int j=0; j<len; j++)
sec[j] = frst[len-j-1];
for(int j=0; j<frst.length;j++)
frst[j] = sec[j]
}
Here what happens.
There are 2 arrays created, the initial one and the second, created inside the doStuff method.
There are 3 references (variables) to the arrays in the code:
external (for the method): d
internal: first and sec.
Inside the doStuff method the second array is indeed populated as the reverse of the initial which is not changed at all.
At the end of the doStuff method both first and sec reference the same object, the second one, and not the original - hence the behavior you see
Example Code
public class test {
public test(){
runTest();
}
private void runTest(){
//method 1
int[] A = {1,2,3,4};
int[] B = new int[A.length];
for (int i = 0; i < A.length; i++){
B[i] = A[i]+1;
}
for (int i: A){
System.out.println(" A: " + i);
}
System.out.println("----------");
for (int i: B){
System.out.println(" B: " + i);
}
System.out.println("----------");
//method 2
int[] C = {1,2,3,4};
int[] D = C;
for (int i = 0; i <D.length; i++){
D[i]++;
}
for (int i: C){
System.out.println(" C: " + i);
}
System.out.println("----------");
for (int i: D){
System.out.println(" D: " + i);
}
System.out.println("----------");
}
public static void main(String[] args){
new test();
}
}
Question
I was running into an issue in one of my methods and found the issue was creating the temporary object altered the original, which I did not want to happen. I was just wondering why this occurs, I was under the impression that setting an object equal to another only points it to that current location/state, not any future updates.
In other words, wanted to know why I have do what I did with int A and int B instead of doing what I did with int C and int D.
To make it even simpler, what is the difference between the two methods above? I'm going to take a stab at it and say the JVM calls the same reference when either int C or int D is called, as I didn't create a new object as I did with the int A int B.
The difference is that with A and B, B is a copy of the array and a completely separate object from A. With C and D, D is another array reference that refers to the same object as C. D continues to refer to not just the "that current location/state", but that same object, until it is reassigned or it goes out of scope. Whatever you do to the object referred to by D will be visible through C as well, as it is the same object.
This question already has answers here:
Java method to swap primitives
(8 answers)
Closed 6 years ago.
I am new to java. How to write the java equivalent of the following C code.
void Swap(int *p, int *q)
{
int temp;
temp = *p;
*p = *q;
*q = temp;
}
Here is one trick:
public static int getItself(int itself, int dummy)
{
return itself;
}
public static void main(String[] args)
{
int a = 10;
int b = 20;
a = getItself(b, b = a);
}
Sorting two ints
The short answer is: you can't do that, java has no pointers.
But here's something similar that you can do:
public void swap(AtomicInteger a, AtomicInteger b){
// look mom, no tmp variables needed
a.set(b.getAndSet(a.get()));
}
You can do this with all kinds of container objects (like collections and arrays or custom objects with an int property), but just not with primitives and their wrappers (because they are all immutable). But the only way to make it a one-liner is with AtomicInteger, I guess.
BTW: if your data happens to be a List, a better way to swap is to use Collections.swap(List, int, int):
Swaps the elements at the specified positions in the specified list.
(If the specified positions are equal, invoking this method leaves
the list unchanged.)
Parameters:
list - The list in which to swap elements.
i - the index of one element to be swapped.
j - the index of the other element to be swapped.
Sorting an int[] array
apparently the real objective is to sort an array of ints.
That's a one-liner with Arrays.sort(int[]):
int[] arr = {2,3,1,378,19,25};
Arrays.sort(arr);
To check the output:
System.out.println(Arrays.toString(arr));
// [1, 2, 3, 19, 25, 378]
And here is a simple helper function to swap two positions in an array of ints:
public static void swap(final int[] arr, final int pos1, final int pos2){
final int temp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = temp;
}
Here's a method to swap two variables in java in just one line using bitwise XOR(^) operator.
class Swap
{
public static void main (String[] args)
{
int x = 5, y = 10;
x = x ^ y ^ (y = x);
System.out.println("New values of x and y are "+ x + ", " + y);
}
}
Output:
New values of x and y are 10, 5
Use this one-liner for any primitive number class including double and float:
a += (b - (b = a));
For example:
double a = 1.41;
double b = 0;
a += (b - (b = a));
System.out.println("a = " + a + ", b = " + b);
Output is a = 0.0, b = 1.41
There are no pointers in Java. However, every variable that "contains" an object is a reference to that object. To have output parameters, you would have to use objects. In your case, Integer objects.
So you would have to make an object which contains an integer, and change that integer. You can not use the Integer class, since it is immutable (i.e. its value cannot be changed).
An alternative is to let the method return an array or pair of ints.
In cases like that there is a quick and dirty solution using arrays with one element:
public void swap(int[] a, int[] b) {
int temp = a[0];
a[0] = b[0];
b[0] = temp;
}
Of course your code has to work with these arrays too, which is inconvenient. The array trick is more useful if you want to modify a local final variable from an inner class:
public void test() {
final int[] a = int[]{ 42 };
new Thread(new Runnable(){ public void run(){ a[0] += 10; }}).start();
while(a[0] == 42) {
System.out.println("waiting...");
}
System.out.println(a[0]);
}
What about the mighty IntHolder? I just love any package with omg in the name!
import org.omg.CORBA.IntHolder;
IntHolder a = new IntHolder(p);
IntHolder b = new IntHolder(q);
swap(a, b);
p = a.value;
q = b.value;
void swap(IntHolder a, IntHolder b) {
int temp = a.value;
a.value = b.value;
b.value = temp;
}
Snippet-1
public int[] swap1(int[] values) {
if (values == null || values.length != 2)
throw new IllegalArgumentException("parameter must be an array of size 2");
int temp = values[0];
values[0]=values[1];
values[1]=temp;
return values;
}
Snippet-2
public Point swap2(java.awt.Point p) {
if (p == null)
throw new NullPointerException();
int temp = p.x;
p.x = p.y;
p.y = temp;
return p;
}
Usage:
int[] values = swap1(new int[]{x,y});
x = values[0];
y = values[1];
Point p = swap2(new Point(x,y));
x = p.x;
y = p.y;
Java uses pass-by-value. It is not possible to swap two primitives or objects using a method.
Although it is possible to swap two elements in an integer array.
You cannot use references in Java, so a swap function is impossible, but you can use the following code snippet per each use of swap operations:
T t = p
p = q
q = t
where T is the type of p and q
However, swapping mutable objects may be possible by rewriting properties:
void swap(Point a, Point b) {
int tx = a.x, ty = a.y;
a.x = b.x; a.y = b.y;
b.x = t.x; b.y = t.y;
}
You have to do it inline. But you really don't need that swap in Java.
Your swap function is essentially changing the values in two pieces of memory. Anything referencing those bits of memory will now get different values.
In Java there aren't really pointers, so this won't work. Instead, references are held on objects, and you can only change stuff inside the objects. If you need to reference one object in two places, so that you can pass the same values around the system and have things react to them changing, try something like the repository pattern or dependency injection.
We can only guess at why you needed this code in C. The only advice I can give is to think about the changes to the objects which you want to achieve, preferably add a method on the actual objects rather than pulling their internals out, and call that method instead. If this doesn't help you, try posting the calling code as we'll probably have a good idea of how to solve the real problem Java-style.
Java is pass by value. So the swap in the sense you mean is not possible. But you can swap contents of two objects or you do it inline.
You can swap variables with or without using a temporary variable.
Here is an article that provides multiple methods to swap numbers without temp variable :
http://topjavatutorial.com/java/java-programs/swap-two-numbers-without-a-temporary-variable-in-java/
You can easily write one yourself.
given:
int array[]={1,2};
you do:
int temp=array[0];
array[0]=array[1];
array[1]=temp;
And you're done. 3 lines of code.
Swapping by using pointer is not possible in java. However, you can implement swapping by passing array containing two objects.
Code goes like this:
public class Swap {
public static void swap(String [] a){
String temp;
temp = a[0];
a[0] = a[1];
a[1] = temp;
}
public static void main(String [] args){
String [] foo = new String[2];
foo[0] = "str1";
foo[1] = "str2";
swap(foo);
System.out.println("First value: "+ foo[0]);
System.out.println("Second value: "+ foo[1]);
}
}
Output:
First value: str2
Second value: str1
public class swaptemp {
public static void main(String[] args) {
String s1="10";
String s2="20";
String temp;
System.out.println(s1);
System.out.println(s2);
temp=Integer.toString(Integer.parseInt(s1));
s1=Integer.toString(Integer.parseInt(s2));
s2=Integer.toString(Integer.parseInt(temp));
System.out.println(s1);
System.out.println(s2);
}
}
//here is also another answer:
class SwapDemo{
static int a=1, b=2 ;
public static void main(String [] args){
Swap swp = new Swap();
swp.swaps(x,y);
System.out.println( " a (was 1)now is " + a + " b (was 2) now is " + b);
}
}
class Swap{
void swaps(int c, int d){
SwapDemo f = new SwapDemo();
f.a = c;
f.a = d;
}
}
class Swap2Values{
public static void main(String[] args){
int a = 20, b = 10;
//before swaping
System.out.print("Before Swapping the values of a and b are: a = "+a+", b = "+b);
//swapping
a = a + b;
b = a - b;
a = a - b;
//after swapping
System.out.print("After Swapping the values of a and b are: a = "+a+", b = "+b);
}
}