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上的所有函数都会使其成为预定副本。 相反,特别是如果你使用headtail递归迭代列表,我会看到你是否可以试图在Sequence上的这个包装的想法。 Sequence的整个存在点是对集合的懒惰工作。

编辑2:显然sublist()创建一个视图,因此已经懒惰。 基本上,我刚刚教你如何创建子列表的实现,除了我缩小到只有尾部。

所以,在这种情况下,只需使用sublist()为您的尾巴功能。