【问题标题】:Java: Sort an unmodifiable listJava:对不可修改的列表进行排序
【发布时间】:2010-12-20 07:58:33
【问题描述】:

如何做到这一点?

我已尝试创建一个新的空列表,然后将不可修改的列表元素复制到其中,但出现了不受支持的操作错误。

感谢任何帮助。

【问题讨论】:

  • 你能显示你用来复制列表的代码吗?

标签: java list sorting collections


【解决方案1】:
    List unmodifiableList = Collections.unmodifiableList(list);

    List newList = new ArrayList(unmodifiableList);

    Collections.sort(newList);

ArrayList 的构造函数采用现有列表,读取其元素(无需修改它们!),并将它们添加到新列表中。

【讨论】:

    【解决方案2】:

    FWIW,google-collections 是单线:

    List<Foo> sorted = Ordering.natural().sortedCopy(unmodifiableList);
    

    【讨论】:

    • 看起来像广告……我喜欢。
    • 仅仅因为有“google”这个词? :p 无论如何。这是一个广告。一种可能是无偿的。
    【解决方案3】:

    您是否正在使用Collections.emptyList() 创建一个空列表?如果是这样,那也是一个不可修改的列表,这可能是您问题的根源。

    使用您的 List 实现的构造函数创建一个新列表,例如 new ArrayList()。您可以将原始列表传递给构造函数,或者使用addAll() 方法。

    【讨论】:

      【解决方案4】:

      在 Java 8 中,您可以使用流 API。例如:

      List<?> sortedList = unsortedList.stream().sorted().collect(Collectors.toList());
      

      【讨论】:

      • 这种方法的另一个优点是您可以将 Comparator 传递给 sorted 方法以实现自定义排序顺序。
      • 这在问题是不可修改的列表的情况下不起作用。
      • @ShaileshVikramSingh 它应该适用于不可修改的列表,是什么让你认为它不起作用?
      【解决方案5】:

      它应该像描述的那样工作。不可修改列表中的元素本身不是不可修改的。当然你不能对一个不可修改的 List 进行排序,因为它必须用 add 和 delete 操作来重写,而那些是不允许的。

      猜测错误在其他地方,最好是显示您的代码:)

      【讨论】:

        【解决方案6】:

        我会回答你的第二个问题:

        您不能添加到“taskListModifiable”列表中,因为这是一个“不可修改”列表,在 Java 中意味着它是不可变的。不能以任何方式直接更改任何类型的不可修改/不可变列表或集合 - 您不能向其中添加元素、从中删除元素或更改对现有元素的引用。

        请注意,如果列表/集合中的现有元素本身是可变的,则它们可能会被更改,但列表中对它们的引用不能更改。也就是说,在列表完全超出范围并被垃圾回收之前,不可修改的列表将始终包含这些相同的引用。

        现在,在您的情况下,Collections.emptyList() 返回一个不可修改的 EMPTY 列表。这实际上总是同一个实例,因为它是不可变的并且总是空的。由于无法扩展(添加到)不可变列表的规则,您无法添加到它。因为它是空的,所以它里面也没有什么可以改变的。

        我应该更清楚地说明 Collection.emptyList() 不会创建一个空列表。它只是返回一个对单例列表实例的引用。

        【讨论】:

        • 不可修改的 IS NOT 在 Java 中是不可变的!!如果在list1 之后创建一个不可修改的列表,然后向list1 添加/删除对象,那么不可修改的列表将反映所做的更改。
        • 这适用于任何语言,其中不可修改的集合只是包装了另一个集合(例如,不制作安全副本),而不仅仅是 Java。您正在谈论保留对包装对象的引用并对其进行更改。但是,我正在对另一个答案发表评论(我不能这样做),他们问他们为什么不能更改创建它的特定 taskListModifiable:taskListModifiable = Collections.emptyList()代码&gt;。事实上,在所有情况下,这都是不可变的,因为 emptyList() 返回一个不可变的、单例的、空列表。
        • @True Soft:是的,你是对的,一些“不可修改”列表中的后备列表实际上是可修改的。确实,它不是严格不可变的,而且您不一定要这样对待它。但是,实际上您通常可以,如果您创建列表,然后使其不可修改,然后丢弃指向列表的初始指针。
        猜你喜欢
        • 1970-01-01
        • 2013-07-09
        • 2014-06-21
        • 1970-01-01
        • 2018-10-20
        • 2020-04-13
        • 2020-09-13
        • 1970-01-01
        • 2012-04-09
        相关资源
        最近更新 更多