为啥 collections.sort 在 Java 中按比较器排序时会抛出不支持的操作异常?

Posted

技术标签:

【中文标题】为啥 collections.sort 在 Java 中按比较器排序时会抛出不支持的操作异常?【英文标题】:Why does collections.sort throw unsupported operation exception while sorting by comparator in Java?为什么 collections.sort 在 Java 中按比较器排序时会抛出不支持的操作异常? 【发布时间】:2014-03-18 05:46:48 【问题描述】:

以下是我用于按预定义顺序对列表进行排序的代码。 itemsSorted 列表中提到了定义的顺序。

final List<String> itemsSorted = myMethod.getSortedItems();

List<String> plainItemList = myMethod2.getAllItems();

final Comparator<String> comparator = new Comparator<String>()         

    public int compare(String str1, String str2) 
        return orderOf(str1) - orderOf(str2);
    

    private int orderOf(String name)           
        return ((itemsSorted)).indexOf(name);
    
 ;
 Collections.sort(plainItemList, comparator);
 return plainItemList;

以上代码抛出

Caused by: java.lang.UnsupportedOperationException
    at java.util.Collections$UnmodifiableList$1.set(Collections.java:1244)
    at java.util.Collections.sort(Collections.java:221)

我不确定为什么该列表不可修改。请帮我解决这个问题。

【问题讨论】:

那么...myMethod2.getAllItems() 返回什么?您需要提供足够的信息来提供帮助。我们看不到您的代码。 这取决于列表的创建方式。给我们看myMethod2.getAllItems()的代码 这不是 Collections$ UnmodifiableList $1 响铃吗? 那么 Cassandra 将返回一个不可修改的列表 为什么是不可变列表? ***.com/questions/16891659/… 【参考方案1】:

该列表不可修改,显然您的客户端方法正在创建一个不可修改的列表(使用例如Collections#unmodifiableList 等)。只需在排序前创建一个可修改的列表:

List<String> modifiableList = new ArrayList<String>(unmodifiableList);
Collections.sort(modifiableList, comparator);

【讨论】:

Arrays.asList 总是可以修改的。它只是不可调整大小 @qqilihq 我只是对你的意见感到好奇——这 UnsupportedOperationException 是不是 Collections 的不良设计和违反 SOLID 原则(即 Liskov 替代原则)的示例。直到运行时才中断。 Collections.sort 只需要 List 接口,而它在某些实现上会中断。这种就地排序的事情不是一个整体的坏主意吗?更清洁的方法会返回排序的Iterable,你认为吗? @VarvaraKalinina 我倾向于同意。例如。 C# (afaik?) 有一个明确的 ImmutableList 类型。我认为类似的构造可以通过 Java 中的 3rd 方库获得,但与现有 API 的互操作性当然会很糟糕。恕我直言,Iterable 只会让事情变得更好一点,因为Iterator 再次有一个remove 方法,它允许修改(这意味着,最后这个方法必须再次抛出一个UnsupportedOperationException 来表示它不允许修改)。 @qqilihq 我有一点Java的C#背景,与C#的LINQ和具有非常简洁的接口的基本集合相比,Java的集合接口有时感觉像是一个醉汉写的。为什么Iterator 确实有remove 方法? C# 的 Enumerator 没有。

以上是关于为啥 collections.sort 在 Java 中按比较器排序时会抛出不支持的操作异常?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Collections.sort 使用 Mergesort 而 Arrays.sort 不使用?

为啥 collections.sort 在 Java 中按比较器排序时会抛出不支持的操作异常?

█■为啥要用实现接口的类实例化接口呢?

Java:Collections.sort和Arrays.sort的区别

关于Java中Collections.sort和Arrays.sort的稳定性问题

Collections.sort() in JDK1.6