1

I am in a situation where I just need to sort an Arraylist of custom object on a class member field. I need that just for displaying some information to the user. I tried with comparator but it's modifying the actual List which I don't want. So for a work around, I did a deep copy of my Arraylist and sorted that cloned Arraylist. Is there an memory efficient way of doing that without making a duplicate Arraylist?

3 Answers3

4

Well, you don't actually need to make a deep copy unless your Comparator is mutating your objects, which it shouldn't. The easiest way is therefore to make shallow copy:

ArrayList<String> original = new ArrayList<>();
ArrayList<String> copy = new ArrayList<>(original);
copy.sort(Comparator.naturalOrder());

Replace Comparator.naturalOrder() with your actual Comparator implementation. For example, if you are comparing a member field, you can use Comparator.comparing as an easy way to create your desired Comparator.

And to answer your question: No, it's not possible without an additional data structure because on the one hand you want to alter the order of the elements, i.e. sort them, and on the other hand you want them to stay in the same order.

Alex R
  • 3,139
  • 1
  • 18
  • 28
  • But isn't shallow copy of the pointers in the ArrayList points to the same elements in the original list? Change in any one of the Arraylist will modify the original list? – Ishratur Rahman May 27 '20 at 01:22
  • By making a shallow copy you only copy the pointers, not the elements. Your second list then sorts these pointers according to some criterion. Also, you wrote you need to display the elements, not alter them. – Alex R May 27 '20 at 01:26
  • Thanks your solution worked. But if I do Arraylist copy = original and then sorting copy also sorts the original list. But doing ArrayList copy = new ArrayList<>(original) soes not change the original. Why is that? – Ishratur Rahman May 27 '20 at 01:36
  • @IshraturRahman If you write `Arraylist copy = original` then `copy` is just an alias for `original`, i.e. the both point to the samy `ArrayList` object. If you instead write `= new ArrayList<>(original)` a new `ArrayList` object is created which has its own internal array for storing the pointers, hence `original` isn't modified when you sort the copy. – Alex R May 27 '20 at 01:39
  • @ Alex R so what's the difference between this approach and deep copy? Thanks – Ishratur Rahman May 27 '20 at 02:00
  • 1
    @IshraturRahman Take a look at the answers of this question https://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy – Alex R May 27 '20 at 02:17
0

as I understood you wanna print your arraylist sorted without change its original sort. if that what you need you can make a temp arraylist or just an array and save sorted items in it then print them finally delete it (in java if you declared a local scope variable it will be deleted when the program leave its scope)

0

You can use streams. Just stream the original list, sort the elements, and create a new list. But the Objects in the list must implement the Comparable interface or you will need to create a Comparator to control the sort.

List<Integer> newList =
                original.stream().sorted(Comparator.naturalOrder())
                        .collect(Collectors.toList());

Say you had a Student class and you wanted to sort a list of students by age. Assume that you had a getAge method you could do it like this.

List<Student> newList =
                listOfStudents.stream().sorted(Comparator.comparing(Student::getAge))
                        .collect(Collectors.toList());

Neither of the above methods alter the original list.

WJS
  • 36,363
  • 4
  • 24
  • 39