我试图在List<T>
中找到尾部函数,但是我找不到任何东西。我最终这样做了。Kotlin List尾部函数
fun <T> List<T>.tail() = this.takeLast(this.size -1)
有没有更好的方法来做到这一点?
我试图在List<T>
中找到尾部函数,但是我找不到任何东西。我最终这样做了。Kotlin List尾部函数
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的解决方案将工作,但他们自动创建原始列表的渴望副本(sans第一elem ent),这对于较大的列表可能需要很长时间。我会用一个包装定义它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()
如果你真的需要它,我可以添加一个更新,使过去的三个成员函数,使他们不急于做副本。
编辑: 注意:如果你遵循的科特林沿袭至今的惯例,你不会让List
的尾巴偷懒,像这样的,因为他们所有的功能上List
让渴望副本。相反,特别是如果您使用head
和tail
递归遍历列表,我会看到您是否可以以某种方式在Sequence
上尝试此封装器的想法。 Sequence
的整个存在点是对收藏的懒惰工作。编辑2: 显然sublist()创建一个视图,因此已经是懒惰的。从本质上讲,我只是教你如何创建子列表的实现,除了我缩小到只有尾部。
所以,在这种情况下,只需使用sublist()为您的尾巴功能。
为什么不使用Java的'sublist'?它完全一样,它创建了原始列表的视图。 https://docs.oracle.com/javase/7/docs/api/java/util/List.html#subList(int,%20int) – hotkey
这不就是序列的用途吗? –
@hotkey我没有意识到子列表是意见。很高兴知道。 –
如果您不想复制列表(在很多情况下很好,CPU缓存和较小的列表都可以),那么请查看Java标准“子列表”以获取扩展https:/ /docs.oracle.com/javase/7/docs/api/java/util/List.html#subList(int,%20int)(根据下面评论中的@hotkey) –