-1
    public class Test {
  public static void main(String[] args) {
    int[] oldList = {1, 2, 3, 4, 5};
    reverse(oldList);
    for (int i = 0; i < oldList.length; i++)
      System.out.print(oldList[i] + " ");
  }

  public static void reverse(int[] list) {
    int[] newList = new int[list.length];

    for (int i = 0; i < list.length; i++)
      newList[i] = list[list.length - 1 - i];

    list = newList;
  }
}

how come the method does not apply and still get 1 2 3 4 5? thank you !

MasterYoshi
  • 57
  • 1
  • 7
  • 1
    Because [Java is pass-by-value](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value). And on reference-level, this means that the location to which it references, is passed. If you re-assing a parameter, this will not be seen at the calling site. – Turing85 Jun 18 '18 at 16:09

4 Answers4

3

This is happening because Java is pass by value. This means that when you pass an argument into a method you are passing the reference to it, not the argument itself. The changes that you make inside the method are resolved but in this case you don't return the modified argument. Try this simple experiment to see what I mean:

public static void main(String[] args) {
    int x = 0;
    foo(x);
    System.out.println(x);
}
public static void foo(int x) {
    x = 4;
}

This program will print 0 because the changes are essentially discarded. To return the copied reference try this:

public static int[] reverse(int[] list) {
    int[] newList = new int[list.length];

    for (int i = 0; i < list.length; i++) {
      newList[i] = list[list.length - 1 - i];
    }

    return newList;  
}

And in your main:

oldList = reverse(oldList);

A much more in depth answer:

Is Java "pass-by-reference" or "pass-by-value"?

GBlodgett
  • 12,704
  • 4
  • 31
  • 45
1

There are couple of issues. You can fix it with below two Options:

Option 1:

1) Make a new copy of original array and use it as reference array to reverse

2) In reverse function, update values of array that has been passed in parameter and reverse it using reference array

public class Test {

    public static void main(String[] args) {
        int[] oldList = {1, 2, 3, 4, 5};
        reverse(oldList);
        for (int i = 0; i < oldList.length; i++)
          System.out.print(oldList[i] + " ");

    }


     public static void reverse(int[] list) {
            // create a copy of initial array to use it to reverse
            int[] newList = Arrays.copyOf(list,list.length);
            for (int i = 0; i < list.length; i++)
              // update original array and reverse it. Calling method still have reference to this array
              list[i] = newList[list.length - 1 - i];
          }
}

Console Output:

enter image description here

PS: Here the idea is to ensure the reference of array remains the same. You can do it using another array as reference array or using another local variable and swapping two values inside array or doing XOR between i and n-i-1 variable. There are n number of ways out of which 1 has been shared above.

Option 2:

1) No need to copy the reference of the old array to new array in reverse method

2) Return the new array reference back to the calling method

3) For above point you will also have to change the return type of reverse function

4) Save the new reference of array in a variable in the main method and then print from the same.

Please find my comments below:

public class Test {

    public static void main(String[] args) {
        int[] oldList = {1, 2, 3, 4, 5};
        //save the return list to a variable
        int[] newList= reverse(oldList);
        for (int i = 0; i < newList.length; i++)
            //print the data from new list
          System.out.print(newList[i] + " ");

    }

    // change the return type
     public static int[] reverse(int[] list) {
            int[] newList = new int[list.length];
            for (int i = 0; i < list.length; i++)
              newList[i] = list[list.length - 1 - i];
            //remove this line as there is no point of copying old array  back to new array
            // list = newList;
            //retrun newlist reference to the calling method
            return newList;     
          }
}

Console Output:

enter image description here

Aman Chhabra
  • 3,824
  • 1
  • 23
  • 39
  • Uhm... no. In order to get it working, OP needs to either work in-place or return the new array. – Turing85 Jun 18 '18 at 16:11
  • @Turing85 I agree. With a first look I thought that was the only issue, but then there are lot of things that needs to be updated. I have updated my answer as well to share the information in detail. – Aman Chhabra Jun 18 '18 at 16:15
  • If you want to work in-place, there is no need to copy the whole array. – Turing85 Jun 18 '18 at 16:32
  • @Turing85 The new array has just been created to refer the copy of array while reversing. There are other ways as well like swapping two variables i and n-i-1 using another variable or doing xor between i and n-i-1 to swap the values and hence reversing array. But in all , it will keep the idea same to not to change the reference of the array in Option 1. I have also updated the same in my answer. – Aman Chhabra Jun 18 '18 at 16:35
0

Java is always pass-by-value. What does this mean for object- and array-references? In Java, we handle objects only through references. References live on the stack, the actual objects live on the heap. References store the address where the actual object resides.

If you pass an object to a method, the reference-value (i.e. the address where the object resides) is passed as parameter. For some method foo(Object o) this means: if you re-assign o in foo's body (e.g. through o = new Object();, this change will not be visible outside the method.

To fix you problem, you would either have to do the reversal in-place (i.e. on list directly) or return your newly created array. Here is an implementation of the in-place variant:

public static void reverse(final int[] values) {
    final int length = values.length;
    for (int i = 0; i < length / 2; ++i) {
        final int j = length - i - 1;
        swap(values, i, j);
    }
}

public static void swap(final int[] values, final int i, final int j) {
    int tmp = values[i];
    values[i] = values[j];
    values[j] = tmp;
}

For an implementation of the return-variant, look at one of the other answers since every other answer seems to implement a variant on this.


Some remarks on your code:

  • Giving an array-parameter the name list is confusing. A list is not the same as an array, the are different datastructures with differen properties.

  • You should never neglect the optional parentheses around one-line if-, else-, for-,... bodies. This can be the source of nasty bugs and is regarded as bad practice.

  • You should take a little bit more care wrt. your indentation. Keep in mind that your source code is a means of coummuncation. The more semantics you can transport through simple rules (like indentation), the easier it is to understand your source code.

Turing85
  • 18,217
  • 7
  • 33
  • 58
0

This is happening because you are altering the new area, and the statement list = newList; does not affect the original list because java is pass by value and you only overwrite the pointer in the reverse function.

Instead you should return the new array and overwrite the old one like:

public class HelloWorld
{

  public static void main(String[] args) {
        int[] oldList = {1, 2, 3, 4, 5};
        oldList = reverse(oldList);
        for (int i = 0; i < oldList.length; i++)
          System.out.print(oldList[i] + " ");
      }

      public static int[] reverse(int[] list) {
        int[] newList = new int[list.length];
        for (int i = 0; i < list.length; i++)
          newList[i] = list[list.length - 1 - i];
        return newList;
      }
    }
Sven Hakvoort
  • 3,543
  • 2
  • 17
  • 34