如何使用 RX 正确清理从服务器接收的项目列表 |过滤器{} 地图{}

How to properly sanitize a list of items received from server using RX | filter{} map{}

我有以下代码,我试图将其用于两个目的:

1) 调用一个 API 并获得作为 POJO

的结果

2) 在 UI 中显示此对象 (POJO) 之前对其进行清理

   private fun getWinbackDataItems(rewardPurpose: String) /*Single<WinbackBaseItem>*/ {
        val x = repository.getRewardsList(rewardPurpose)
            .filter {
                it.result?.rewards != null
            }.map { winback ->
           winback.result?.rewards?.asSequence()?.filter { rewardsItem ->
                rewardsItem?.id != null && rewardsItem.title != null
            }?.toList()?.take(3)?.map {
                WinbackListItem(it?.id, it?.title!!, false)
            }?.toList()
        }
    }

我的争论点是下面这行:

 itemListSanitized.add(WinbackListItem(it.id, it.title, false))

此时我假设过滤器已经从原始列表中删除了所有空值,但令我惊讶的是我发现我必须在将它们添加到新列表时对它及其所有内容进行空值检查。

我在这里错过了什么,原谅我的天真,因为我刚刚开始反应

我认为您不是在反对执行代码,而是在反对您的 IDE 的警告消息或此代码编译的能力。您可能 运行 反对的是,早期对 null 的检查不一定允许编译器稍后假定 non-null 值,因为与此同时,其他代码在不同的线程可能有 运行 并更改了值。

因此,当您创建 WinbackListItem 时,您可以安全地假设某些项目不为空,但编译器无法确定这一点,因为它不知道您的进程中还发生了什么 space。因此编译器要求您告诉它不要担心空值 (!!) 或者您再次检查这些值。这就是 Kotlin 的工作方式。它通常是 PITA,但它就是这样。

我试过发布的代码只是为了确定我知道我在说什么。这是我能够 运行:

的代码
private fun getWinbackDataItems(rewardPurpose: String) /*Single<WinbackBaseItem>*/ {
    val x = repository.getRewardsList(rewardPurpose)
        .filter {
            it.result?.rewards != null
        }.map { winback ->
            winback.result?.rewards?.asSequence().filter { rewardsItem ->
                rewardsItem.id != null && rewardsItem.title != null
            }.toList().take(3).map {
                println(it.id)
                println(it.title)
                WinbackListItem(it.id!!, it.title!!, false)
            }.toList()
        }.count()
}

我创建了一些非常简单的类和对象来满足这段代码,让它运行。请注意,我删除了一些不必要的“?”空检查。我一直在研究输入值,直到我确信 it.idit.title 在调用 WinbackListItem 构造函数时永远不会是 null。然而,考虑到不接受 null 参数值的 WinbackListItem 定义,其参数上的两个 !! 或其他确保它们不是 null 的内容是必需的:

class WinbackListItem(val id: Int, val title: String, val huh: Boolean)