You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JUnit中使用CustomComparator排序抛UnsupportedOperationException的修复

异常排查与修复方案

根因定位

从堆栈里的com.google.common.collect.UnmodifiableListIterator.set调用链可以直接定位问题:你代码中操作的Database.arrayList本质是Guava生成的不可变只读列表,并非可变的ArrayList实例。
Collections.sort的实现原理是通过列表迭代器的set方法逐次调整元素位置完成排序,一旦遇到不支持元素修改的只读列表,就会直接抛出UnsupportedOperationException。哪怕变量名叫arrayList,只要实际引用的是不可变集合,就会触发这个异常。

可选修复方案

  • 方案1:排序前拷贝为可变列表(兼容存量代码)
    不要直接对原不可变列表执行排序操作,先把列表内容拷贝到真正可变的ArrayList实例上再执行排序逻辑:

    // 拷贝生成可修改的可变列表
    List<MyObject> sortableData = new ArrayList<>(Database.arrayList);
    // 对可变副本执行排序
    Collections.sort(sortableData, new CustomComparator());
    // 如果需要回写排序结果到原存储对象,批量更新即可
    Database.arrayList.clear();
    Database.arrayList.addAll(sortableData);
    
  • 方案2:流式生成排序后的新列表(无侵入最安全)
    基于Java 8+的Stream API直接生成排序后的新列表,全程不修改原列表内容,从根本上规避不可变集合的操作限制:

    List<MyObject> sortedData = Database.arrayList.stream()
            .sorted(new CustomComparator())
            .collect(Collectors.toCollection(ArrayList::new));
    
  • 方案3:从源头修正列表初始化逻辑
    排查Database.arrayList的赋值来源,避免把以下类型的不可变集合赋值给该变量:

    • Guava的ImmutableList系列实现
    • 经过Collections.unmodifiableList()包装的只读列表
    • Java 9+中List.of()生成的不可变列表
      直接用new ArrayList<>()初始化真正可变的列表,从根源上避免只读实例被传递到业务逻辑层。

额外健壮性提示

当前实现的CustomComparator存在空指针隐患:如果getStartDate()返回null,调用compareTo时会直接抛出空指针异常。可以在比较逻辑中补充空值判断,约定null值的排序优先级,提升代码稳定性。

内容的提问来源于stack exchange,提问作者Ady96

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 10:36:08