lelelo
lelelo

Reputation: 173

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.

Upvotes: 3

Views: 1346

Answers (4)

Juan Carlos Mendoza
Juan Carlos Mendoza

Reputation: 5814

On this line:

ArrayList<Integer> returnList = list;

you are just creating another reference to the same list (Object) in your sorted method and any change that you apply to it using this new reference will be reflected in you original reference because they point to the same object. You can do this to create a new list:

private static ArrayList<Integer> sorted(ArrayList<Integer> list){
    ArrayList<Integer> returnList = new ArrayList<>(list); // the new keyword creates a new object on the memory heap
    Collections.sort(returnList);
    return returnList;
}

This time we are creating another ArrayList Object with the elements of you original list. This way the original list won't change when you sort the newer.

This behaviour doesn't apply on Immutable Objects like String or LocalDateTime. These cannot change their state after being created and instead return a new copy with the changes applied.

Upvotes: 1

Jorge L. Morla
Jorge L. Morla

Reputation: 630

you can use Stream api

List<Integer> list = Arrays.asList(5,8,3,6);

List<Integer> newList = list.stream().sorted().collect(Collectors.toList());

The stream api offers several methods to work with collections immutably. This is the recommended way if you are using Java 8 or later.

Upvotes: 0

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37614

In your sorted method you are still calling Collection.sort on the original list. To avoid this you could create a shallow copy and return that e.g.

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

Upvotes: 3

BambooleanLogic
BambooleanLogic

Reputation: 8171

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.

Upvotes: 4

Related Questions