首页 > 解决方案 > 在 Kotlin 中比较和替换两个不同大小的列表中的项目?

问题描述

我有以下功能:

override fun insertUpdatedItems(items: List<AutomobileEntity>) {
        if (!items.isEmpty()) {
            items.forEachIndexed { index, automobileEntity ->
                if (automobileEntity.id == items[index].id) {
                    automobileCollection[index] = items[index]
                    notifyItemInserted(index)
                }
            }
        }
    }

我正在使用为 recyclerview 提供数据,我正在尝试插入已更新/编辑的项目,这些项目的automobileCollection大小总是返回10项目,但items列表可能会有所1不同10

它应该比较项目,id但我目前使用此功能得到的是已编辑的项目只是插入到 recyclerview 的适配器中,而不是被视为已经存在的项目。

相反,如果我使用迭代,automobileCollection我会得到 IndexOutOfBoundsException,因为大多数时候items列表小于automobileCollection.

标签: androidlistcollectionskotlin

解决方案


要使用另一个列表中的项目更新列表,您可以使用多种方法。

首先从直接替换开始(保留顺序,但这只是一个细节):

val sourceList = TODO()
val targetList = TODO()

targetList.replaceAll { targetItem -> 
  sourceList.firstOrNull { targetItem.id == it.id } 
            ?: targetItem
}

或者删除所有项目并再次添加它们:

targetList.removeIf { targetItem ->
  sourceList.any { it.id == targetItem.id }
}
targetList.addAll(sourceList)

使用 listIterator (注意!当你打电话时,这实际上也在幕后发生replaceAll......不是以相同的方式,但类似;-)):

val iterator = targetList.listIterator()
while (iterator.hasNext()) {
  iterator.next().apply {
    sourceList.firstOrNull { id == it.id }?.also(iterator::set)
  }
}

可能不那么可读......对于你forEachIndexed我没有真正看到任何用例。对于其他问题,肯定存在,但我建议您尽可能多地省略索引(以及forEach)。如果没有更好的想法出现在您的脑海中,那forEach也没关系,但很多时候forEach(甚至更多forEachIndexed)并不是解决问题的最佳方法。


推荐阅读