Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collections.sort sorts the wrong list

I want to create one sorted list out of my original list - without the Collections.sort(list) call changing the original list. So that I have one list unsorted and one being sorted - out of the same list.

Take a look at this code:

public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList();
    list.add(5);
    list.add(8);
    list.add(3);
    list.add(6);
    System.out.println("Before method list is");
    System.out.println(list);
    ArrayList<Integer> theReturnedList = sorted(list);
    System.out.println("After it is");
    System.out.println(list);
}

private static ArrayList<Integer> sorted(ArrayList<Integer> list){
    ArrayList<Integer> returnList = list;
    Collections.sort(returnList);
    return returnList;
}

The list object gets sorted - even though I am not calling the Collection.sort() method onto it. How can I avoid it?

Beacuse I thought this would happen...

public static void main(String[] args) {
    String original = "I am an object created in main";
    String theChangedObject = change(original);
    System.out.println(original);
}

private static String change(String string){
    String changed = string;
    changed = "I was changed";
    return changed;
}

The object orginal stays the same.

like image 461
lelelo Avatar asked May 18 '26 18:05

lelelo


1 Answers

Your problem is a misunderstanding of how references work. Let's take a look at the method:

private static ArrayList<Integer> sorted(ArrayList<Integer> list){
    ArrayList<Integer> returnList = list;
    Collections.sort(returnList);
    return returnList;
}

The line ArrayList<Integer> returnList = list; does not copy the list. It copies the reference to the list. What this means is that returnList and list will both refer to the same list. Changes in one will affect the other, because they are actually just different names for the same thing.

What you want to do is to make a brand new list containing the same values, which can be done with

ArrayList<Integer> returnList = new ArrayList<>();
returnList.addAll(list);

There is also a convenient ArrayList constructor that does this in one step:

ArrayList<Integer> returnList = new ArrayList<>(list);

Changes to returnList will not affect list because they are now two completely independent lists that just happen to contain the same values.

like image 58
BambooleanLogic Avatar answered May 20 '26 07:05

BambooleanLogic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!