【问题标题】:Sort an Arraylist without modifying the original list在不修改原始列表的情况下对 Arraylist 进行排序
【发布时间】:2020-09-13 22:44:54
【问题描述】:

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

【问题讨论】:

    标签: java sorting arraylist comparator


    【解决方案1】:

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

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

    将 Comparator.naturalOrder() 替换为您的实际 Comparator 实现。例如,如果您要比较成员字段,您可以使用Comparator.comparing 作为创建所需Comparator 的简单方法。

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

    【讨论】:

    • 但是 ArrayList 中指针的浅拷贝不是指向原始列表中的相同元素吗?改变任何一个Arraylist都会修改原来的列表吗?
    • 通过进行浅拷贝,您只能复制指针,而不是元素。然后,您的第二个列表根据某些标准对这些指针进行排序。此外,您写道您需要显示元素,而不是更改它们。
    • 感谢您的解决方案有效。但是,如果我执行 Arraylist copy = original 然后排序副本也会对原始列表进行排序。但是做 ArrayList copy = new ArrayList(original) 所以不会改变原来的。这是为什么呢?
    • @IshraturRahman 如果你写Arraylist&lt;String&gt; copy = original,那么copy 只是original 的别名,即两者都指向相同的ArrayList 对象。如果您改为编写= new ArrayList&lt;&gt;(original),则会创建一个新的ArrayList 对象,该对象具有自己的内部数组来存储指针,因此在对副本进行排序时不会修改original。
    • @IshraturRahman 看看这个问题的答案stackoverflow.com/questions/184710/…
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      上述方法都不会改变原始列表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-07
        • 2012-03-24
        • 2012-08-25
        • 2023-03-28
        • 1970-01-01
        • 2018-01-12
        • 1970-01-01
        相关资源
        最近更新 更多