当前位置: 首页 > 知识库问答 >
问题:

AbstractList在List上调用. soreption时不支持的操作异常

徐文斌
2023-03-14

我正在使用Collections.sort()对一个列表进行排序,它似乎在我可以测试的每一个方面都工作正常。我的一些用户崩溃了。

Caused by java.lang.UnsupportedOperationException
    java.util.AbstractList.set (AbstractList.java:681)
    java.util.AbstractList$FullListIterator.set (AbstractList.java:143)
    java.util.Collections.sort (Collections.java:1909)
    com.myapp.MyFragment.myMethod (MyFragment.java:225)

但是,我所做的只是尝试对列表进行html" target="_blank">排序

private void myMethod(List<MyThing> myThings) {

    Collections.sort(myList, (thing1, thing2) -> Long.compare(thing2.getLongValue(), thing1.getLongValue()));

我注意到这在Android 8及更高版本上不会发生。它只发生在5.0 - 7.1上

该列表被实例化为ArrayList,被填充,并被设置为作为泛型列表的类的实例的成员。然后用EventBus发布这个对象。然后使用Kotlin的< code>map和< code>sortedByDescending函数对列表进行映射和排序。然后将映射和排序后的列表传递给< code>myMethod()

此Kotlin扩展正在生成传递给此方法的列表:

fun List<MyThing>.mapAndSort(context: Context): List<MyThing> {
    return mapNotNull {
        when (it.type) {
            type -> it.getTyped(context) //all of these return polymorphic MyThings
            anotherType -> it.getAnotherTyped(context)
            someOtherType -> it.getSomeOtherTyped(context)
            yetAnotherType -> it.getYetAnotherType(context)
            yetOneMoreType -> it.getYetOneMoreType(context)
            finallyLastTyope -> it.getFinallyLastType(context)
            else -> null
        }
    }.sortedByDescending { it.longValue }
}

到目前为止,我已经看到这个列表是一个java.util.数组$数组列表,以及kotlin.collections.EmptyList

我认为这与EventBus有关,但可能是Kotlin传递了一个Kotlin集合列表类型。有人知道到底发生了什么吗?

共有2个答案

颛孙高义
2023-03-14

这次崩溃的根源似乎是,在内部,Iterable

public fun <T> Iterable<T>.sortedWith(comparator: Comparator<in T>): List<T> {
    if (this is Collection) {
       if (size <= 1) return this.toList() // <-- HERE
       @Suppress("UNCHECKED_CAST")
       return (toTypedArray<Any?>() as Array<T>).apply { sortWith(comparator) }.asList()
    }
    return toMutableList().apply { sortWith(comparator) }
}

函数toList()将依次调用listOf:

public fun <T> Iterable<T>.toList(): List<T> {
    if (this is Collection) {
        return when (size) {
            0 -> emptyList()
            1 -> listOf(if (this is List) get(0) else iterator().next())
            else -> this.toMutableList()
        }
    }
    return this.toMutableList().optimizeReadOnlyList()
}

这反过来将解析为空列表(可以安全排序,因为它是空的)或单例列表,它不从抽象列表中实现

以下是一些证据:

https://try . kotlinlang . org/#/user projects/s3j 6g 8476h 8047 vvvsjuveletlr/rjlkkn 3n 6117 C1 AAG ja 8 dr 1h 67

我们可能有一个错误,或者至少是一个改进,因为排序如果它是List类型它可能会返回

public fun <T> Iterable<T>.sortedWith(comparator: Comparator<in T>): List<T> {
    if (this is Collection) {
       if (size <= 1) return if(this is List<T>) this else this.toList()
       @Suppress("UNCHECKED_CAST")
       return (toTypedArray<Any?>() as Array<T>).apply { sortWith(comparator) }.asList()
    }
    return toMutableList().apply { sortWith(comparator) }
}

文凯康
2023-03-14

集合排序是一个就地列表变异操作。如果要在 Java 方法中调用它,请只传递一个静态已知为 Kotlin 中的可变列表的列表。

如果您有一个具有未知可变性的List,您可以通过调用从中获得一个 。toMutableList() 扩展函数。

如果用 Java 编写 myMethod 对你来说不是原则,你可以用 list.sorted 按降序 { it.longValue } 调用 Kotlin 替换它,那么你就不需要先将该列表变成可变列表。事实上,这就是 mapAndSort 方法最终所做的,所以看起来没有必要再次对其进行排序。

 类似资料:
  • 相反,将引发“UnsupportedOperationException”。看起来ContainerRequest没有从修改的请求中提取UserPrincipal。 修改是通过 问题是如何将主体信息从HttpServerProbe传输到ContainerRequestFilter。request具有安全信息(在本例中是SSL客户机证书信息),而com.sun.jersey.spi.containe

  • 我不知道;我不太明白在哪里可以抛出这个异常。 例如,我正在实现

  • 下面是在strList5的subList.clear()调用中引发异常的代码: 我清除子列表的方式有问题吗?或者这是8Java的臭虫?我的Java8在Mac上的版本是:java版本"1.8.0_45"Java(TM)SE运行时环境(构建1.8.0_45-b14)JavaHotSpot(TM)64位服务器VM(构建25.45-b02,混合模式)

  • 我想从excel(.xlsx)文件中读取超过60万行。 我使用的是ApachePOI和xlsx拖缆。 Apache poi版本为3.15,因为xlsx streamer在上述版本中不支持 我只想迭代特定的列。我尝试过的是: 我得到这个例外,几乎没有警告 第35行是

  • 我正在使用sql server进行数据库连接。并且我希望在运行多个结果集时保持结果集打开。我使用了,但在执行语句时出现以下错误, 由于我是使用sql server的新手,所以我对其中的一些概念还不是很了解。如果有人知道为什么会这样请回答我。

  • 我正在使用 Netty 5.0。 我有一个补充的客户端引导程序,我以安全聊天客户端为例.java来自netty github的例子。Wenn 我从客户端引导程序向服务器发送消息,它工作得很好。当我尝试将消息从服务器引导程序发送到客户端时(首先通过客户端成功启动连接/通道后),我得到一个 没有任何进一步的信息。从服务器向客户端发送消息是通过上面的代码完成的。 服务器引导是否仅用于接收? 服务器引导程