在不修改原始列表的情况下对 Arraylist 进行排序

Sort an Arraylist without modifying the original list

我现在的情况是,我只需要在 class 成员字段上对自定义对象的 Arraylist 进行排序。我需要它只是为了向用户显示一些信息。我尝试使用 comparator 但它正在修改我不想要的实际列表。因此,为了解决这个问题,我对我的 Arraylist 进行了深度复制,并对克隆的 Arraylist 进行了排序。有没有一种内存效率高的方法可以做到这一点而无需创建重复的 Arraylist?

好吧,除非您的 Comparator 正在改变您的对象,否则您实际上不需要制作深拷贝,而这不应该。因此,最简单的方法是进行浅拷贝:

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

Comparator.naturalOrder() 替换为您的实际 Comparator 实施。例如,如果您正在比较成员字段,您可以使用 Comparator.comparing 作为创建所需 Comparator.

的简单方法

然后回答你的问题:不,没有额外的数据结构是不可能的,因为一方面你想改变元素的顺序,即对它们进行排序,另一方面你希望它们保留同样的顺序。

据我了解,您想打印排序后的数组列表而不更改其原始排序。 如果那是你需要的,你可以制作一个临时数组列表或只是一个数组并在其中保存排序的项目然后打印它们最后删除它(在 java 如果你声明了一个局部范围变量,当程序离开它时它将被删除范围)

您可以使用流。只需流式传输原始列表,对元素进行排序,然后创建一个新列表。但是列表中的 Objects 必须实现 Comparable 接口,否则您将需要创建一个 Comparator 来控制排序。

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

假设您有一个 Student class 并且您想要按年龄对学生列表进行排序。假设您有一个 getAge 方法,您可以这样做。

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

以上两种方法都不会改变原始列表。