Reputation: 173
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
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
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
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
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