如何创建具有原始列表的每一秒元素的代理列表



我需要一个包装器列表,它反映像subList()这样的原始列表的所有更改,但只包含每一秒的元素。

我试过了:

fun getWrapperList (original_list: List<T>): List<T> = 
IntRange(0, original_list.size.div(2)).map { original_list[it * 2 + 1] }

但它创建了一个不反映变化的新列表。

我不认为标准库中有任何相关内容,因为这不是常见的需求。(我只记得有几次想要访问替代元素,我应该将代码重构为子对象列表…(

但你可以很容易地创建自己的。

最简单的方法可能是扩展AbstractList,例如:

class AlternateView<T>(val sourceList: List<T>): AbstractList<T>() {
override val size get() = (sourceList.size + 1) / 2
override fun get(index: Int) = sourceList[index * 2]
}

(这给出了第一、第三、第五…项;我相信,如果你想要其他项,你可以看看如何调整它。或者将其作为构造函数参数并同时支持这两项。(

这可以根据需要工作,对原始列表的更改反映在视图中:

val list = mutableListOf(1, 2, 3, 4, 5, 6)
val view = AlternateView(list)
println("list=$list, view=$view") // list=[1, 2, 3, 4, 5, 6], view=[1, 3, 5]
list[0] = 7
list.removeAt(1)
list.add(4, 8)
println("list=$list, view=$view") // list=[7, 3, 4, 5, 8, 6], view=[7, 4, 8]

如果性能很重要,您可能应该考虑重写更多的AbstractList方法,甚至直接实现List。但这可能是一项艰巨的工作,在许多情况下,这个简单的版本就足够了。

您应该能够执行以下操作(使用computed属性(

class SomeClass {
val originalList = mutableListOf(1, 2, 3, 4, 5, 6)
val derivedList: List<Int>
get() = originalList.filterIndexed { index, i -> index % 2 == 0 }
}
fun main()  {
val someClass = SomeClass()
println(someClass.originalList)
println(someClass.derivedList)
someClass.originalList.add(7)
println(someClass.derivedList)
}

上面生成的输出

[1, 2, 3, 4, 5, 6]
[1, 3, 5]
[1, 3, 5, 7]

最新更新