我打算处理一些数据(这是从json对象Nuu解析的列表,在下面的示例中,我只是将列表存根了)。为了处理该集合,我将使用者println传递到getAllNuu方法中,该方法检索并解析该“json”。

虽然,我从json接收的数据包含重复项(基于三个字段的两个[Nuu.loNuu.la],请参见重写的Nuu.equals-生成),所以我想通过使用扩展功能Nuu.merge将它们合并在一起

在尝试编译以下代码之前,我看不到任何错误,然后得到:Error:(7, 5) Kotlin: Type mismatch: inferred type is Collection<Nuu?> but Collection<Nuu> was expected
为什么Kotlin会推断可空对象的集合?它在哪里发生?

我也将感谢任何建议使代码更好或更像kotlin。

我的环境:kotlinc-jvm 1.3.70(JRE 12.0.1 + 12)

码:

    fun main(args: Array<String>) {
        getAllNuu { data -> println(mergeNuus(data)) }
    }

    fun mergeNuus(data: Collection<Nuu>): Collection<Nuu> =
        // grouping two same (based on their equals) elements
        data.groupingBy { it }
     // ^ Error:(7, 5) Kotlin: Type mismatch: inferred type is Collection<Nuu?> but Collection<Nuu> was expected
            // merging the equal elemnts into one
            .aggregate { _, accumulator: Nuu?, element: Nuu, first ->
                if (first)
                    element
                else
                    accumulator!!.merge(element)
            }.values

    // supposedly this is a http request which processes
    // the retrieved data by passed in consumer 'printout'
    fun getAllNuu(printout: (data: Collection<Nuu>) -> Unit) {
        val nuuList = listOf(
            Nuu(3, "t", 1),
            Nuu(5, "6", 2),     // say this is a http request
            Nuu(7, "a", 3),     // just been stubbed with the list
            Nuu(3, "a", 4),
            Nuu(5, "5", 5),
            Nuu(2, "2", 6),
            Nuu(3, "t", 7),
            Nuu(1, "1", 8),
            Nuu(5, "5", 9),
            Nuu(2, "2", 10)
        )
        // processing the data with consumer passed
        // from the main method
        printout.invoke(nuuList)
    }

    data class Nuu(
        val lo: Int,
        val la: String,
        val su: Int
    ) {
        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (javaClass != other?.javaClass) return false
            other as Nuu
            if (lo != other.lo) return false
            if (la != other.la) return false
            return true
        }

        override fun hashCode(): Int {
            var result = lo
            result = 31 * result + la.hashCode()
            return result
        }
    }
    // similarity based on equals, and sumup the field 'su'
    fun Nuu.merge(other: Nuu) = Nuu(lo, la, su + other.su)

谢谢

最佳答案

除了我在注释中提供的解决方法(.aggregate<Nuu, Nuu, Nuu>),它也可以在不指定任何其他类型的情况下工作:

    data.groupingBy { it }
        // merging the equal elemnts into one
        .aggregate { _, accumulator: Nuu?, element: Nuu, first ->
            val res =
                if (first)
                    element
                else
                    accumulator!!.merge(element)
            res
        }.values

这样做的时候,我真的看不到任何原因导致您的代码无法编译,这对我来说似乎是一个编译器错误。当然,我也不明白为什么这里也会发生错误,您没有做任何棘手或异常的事情。

关于kotlin - 推断类型为可为空的集合,但预期为不可为空的集合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60847146/

10-10 19:42