Kotlin List尾巴功能
我正在尝试在List<T>
找到一个尾部函数,但是我找不到任何东西。 我结束了这样做。
fun <T> List<T>.tail() = this.takeLast(this.size -1)
有没有更好的方法来做到这一点?
Kotlin没有内置的List<T>.tail()
函数,所以实现自己的扩展功能是唯一的方法。 虽然你的实现是完美的,但可以简化一下:
fun <T> List<T>.tail() = drop(1)
或者,而不是扩展功能,您可以定义一个扩展属性:
val <T> List<T>.tail: List<T> get() = drop(1) val <T> List<T>.head: T get() = first()
然后像这样使用它:
val list = listOf("1", "2", "3") val head = list.head val tail = list.tail
您和@Vladimir Mironov的解决方案将会起作用,但是他们会自动创建原始列表(不包含第一个元素)的急切副本,这对于更大的列表可能需要很长时间。 我会用一个包装器List
类来定义它,它将其方法委托给包装器,忽略使用索引调整的第一个元素:
private class TailList<T> (private val list: List<T>) : List<T> { override val size: Int get() = list.size -1 override fun isEmpty(): Boolean = size == 0 override fun iterator(): Iterator<T> = listIterator() override fun listIterator(): ListIterator<T> = list.listIterator(1) override fun listIterator(index: Int): ListIterator<T> = list.listIterator(index + 1) override fun subList(fromIndex: Int, toIndex: Int): List<T> = list.subList(fromIndex + 1, toIndex + 1) override fun lastIndexOf(element: T): Int = list.lastIndexOf(element) - 1 override operator fun get(index: Int): T = list[index + 1] // The following member functions require the copy of a new list override fun containsAll(elements: Collection<T>): Boolean = tailList.containsAll(elements) override fun contains(element: T): Boolean = tailList.contains(element) override fun indexOf(element: T): Int = tailList.indexOf(element) private val tailList by lazy { ArrayList(this) } // makes a proper copy the elements this list represents }
注释完成后,您可能会注意到该部分的功能。 为了简单起见,我只做了这个。 为了记忆,我做了一个lazy
tailList
属性
他们都可以通过手动迭代集合来实现,而不是做某种委托。 如果这是你想要的,我相信你可以弄明白。
有了这个,头部和尾部属性变成这样:
val <T> List<T>.tail: List<T> get() = if(this.isEmpty()) throw IllegalStateException("Cannot get the tail of an empty List") else TailList(this) val <T> List<T>.head: T get() = this[0] // or first()
如果你真的需要它,我可以添加一个更新,使最后三个成员函数,使他们不要急于复制。
编辑:注意:如果你遵循Kotlin迄今为止所遵循的约定,那么你不会让List
的尾部像这样懒,因为它们在List
上的所有函数都会使其成为预定副本。 相反,特别是如果你使用head
和tail
递归迭代列表,我会看到你是否可以试图在Sequence
上的这个包装的想法。 Sequence
的整个存在点是对集合的懒惰工作。
编辑2:显然sublist()创建一个视图,因此已经懒惰。 基本上,我刚刚教你如何创建子列表的实现,除了我缩小到只有尾部。
所以,在这种情况下,只需使用sublist()为您的尾巴功能。