1

I'm getting very frustrated from this problem I have. Here is the gist of what is happening:

import static java.lang.System.*;
import java.util.ArrayList;
public class Test {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(12);
        list.add(19);
        list.add(442);
        list.add(3);
        list.add(1);
        list.add(9);
        out.println(list.toString());
        out.println(bubbleSort(list));
        out.println(list.toString());
    }
    public static int bubbleSort(ArrayList<Integer> num) {
        int j;
        boolean flag = true;
        int temp;
        while(flag) {
            flag = false;
            for(j = 0; j < num.size() - 1; j++) {
                if(num.get(j) > num.get(j + 1)) {
                    temp = num.get(j);
                    num.set(j, num.get(j + 1));
                    num.set(j + 1, temp);
                    flag = true;
                }
            }
        }
        return num.get(0);
    }
}

The output is:

[12, 19, 442, 3, 1, 9] 1 [1, 3, 9, 12, 19, 442]

Why is the ArrayList list getting sorted when I call the method bubbleSort()? Shouldn't the method be making an instance of list when I call it as bubbleSort(list) and not sort list itself which is outside its scope? I just want bubbleSort to get the smallest value of list by making an instance of list, sorting that instance using bubble sort, and returning the first value of that instance. Am I missing something really obvious? I've gotten really tired from my frustration over this problem...

parrot15
  • 309
  • 3
  • 13
  • Duplicate? https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value – assylias Jul 24 '17 at 13:13
  • In Java, you make a new instance with the `new` keyword, and you only do it once in your snippet, in `main()`. – Mick Mnemonic Jul 24 '17 at 13:14
  • 1
    @assylias: We really need a canonical for "what is an object reference" that doesn't get into the whole pass-by- thing at all, as it's irrelvant to 95% of the questions where people don't understand this. :-) – T.J. Crowder Jul 24 '17 at 13:20
  • 1
    Possible duplicate of [Is Java "pass-by-reference" or "pass-by-value"?](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – talex Jul 24 '17 at 13:31

2 Answers2

4

Shouldn't the method be making an instance of list when I call it as bubbleSort(list) and not sort list itself which is outside its scope?

No. Passing around the value that refers to an object (called an object reference) doesn't involve copying the object, just the value.

The value in your list variable is an object reference, which tells the JVM where that list object is in memory. (We never see the actual values, but think of them as numbers like ints; they behave exactly like them.) If you pass that value into a method, the method receives a copy of that value (the object reference) — but that object reference still refers to the same object.

It's exactly the same thing as what happens here:

List<String> list1 = new ArrayList<>();
List<String> list2 = list1;

Let's break it down. When we do

List<String> list1 = new ArrayList<>();

the new operator makes the JVM create an ArrayList in memory, and store a reference to that list (a unique identifier for it that the JVM understands) in list1:

list1<Ref22135>−−−+
                  |    +−−−−−−−−−−−−−−+
                  +−−−>| (ArrayList)  |
                       +−−−−−−−−−−−−−−+
                       | count: 0     |
                       | capacity: 16 |
                       | ...          |
                       +−−−−−−−−−−−−−−+

Then when we do this:

List<String> list2 = list1;

that value (shown above as Ref22135, but again, we never see them) is copied into list2:

list1<Ref22135>−−−+
                  |    +−−−−−−−−−−−−−−+
                  +−−−>| (ArrayList)  |
                  |    +−−−−−−−−−−−−−−+
list2<Ref22135>−−−+    | count: 0     |
                       | capacity: 16 |
                       | ...          |
                       +−−−−−−−−−−−−−−+

We now have two copies of the reference to the single object, not two objects.

For the same reason, passing list into bubbleSort copies the value of the list variable (Ref22135 or whatever) into the bubbleSort parameter, not the list itself.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • That makes a lot more sense now, thanks. Although I don't get the purpose of why they made it so that when I pass list into `bubbleSort()` that it makes an instance of the _memory address_, rather than the values of list itself. – parrot15 Jul 24 '17 at 14:25
  • @parrot15: Duplicating an object every time you pass it into a method would be **massively** inefficient (and don't forget it would have to be a deep copy, by definition). Whereas duplicating a reference is a matter of copying four to eight bytes (into JVM registers or onto the stack). – T.J. Crowder Jul 24 '17 at 14:39
0

num has been save by ref and not by value so what you need to do it's that code

import static java.lang.System.*;
import java.util.ArrayList;
public class Test {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(12);
        list.add(19);
        list.add(442);
        list.add(3);
        list.add(1);
        list.add(9);
        out.println(list.toString());
        out.println(bubbleSort(list));
        out.println(list.toString());
    }
    public static int bubbleSort(ArrayList<Integer> num) {
        //copy the array list to new array list
        ArrayList<Integer> numtemp = new ArrayList<Integer>(num);
        int j;
        boolean flag = true;
        int temp;
        while(flag) {
            flag = false;
            for(j = 0; j < numtemp.size() - 1; j++) {
                if(numtemp.get(j) > numtemp.get(j + 1)) {
                    temp = numtemp.get(j);
                    numtemp.set(j, numtemp.get(j + 1));
                    numtemp.set(j + 1, temp);
                    flag = true;
                }
            }
        }
        return numtemp.get(0);
    }
}
Tzach Oren
  • 44
  • 11
  • Exactly what I needed, thanks. My comp sci course never taught me about pass by reference and pass by value... guess I have some reading to do. – parrot15 Jul 24 '17 at 13:21
  • @parrot15: Just to be clear: This is **not** pass-by-reference. "Pass-by-reference" is a term of art referring to passing references to *variables* so the called method can reach out and change the value in the variable. Java never does that. Java does have object references, but those are passed by value just like everything else. – T.J. Crowder Jul 24 '17 at 13:22