Este team de expertos pasados varios días de trabajo y de recopilar de información, obtuvieron la solución, queremos que te sea de gran utilidad en tu proyecto.
Solución:
Kotlin no tiene un incorporado List
función, por lo que implementar su propia función de extensión es la única forma. Aunque su implementación está perfectamente bien, se puede simplificar un poco:
fun List.tail() = drop(1)
O, en lugar de la función de extensión, puede definir una propiedad de extensión:
val List.tail: List
get() = drop(1)
val List.head: T
get() = first()
Y luego úsalo como:
val list = listOf("1", "2", "3")
val head = list.head
val tail = list.tail
Tuya y las soluciones de @Vladimir Mironov voluntad funcionan, pero automáticamente crean copias ansiosas de la lista original (sin el primer elemento), lo que puede llevar mucho tiempo para listas más grandes. Yo lo definiría con un envoltorio List
clase que delega sus métodos al envuelto, ignorando el primer elemento usando ajustes de índice:
private class TailList (private val list: List) : List
override val size: Int
get() = list.size -1
override fun isEmpty(): Boolean = size == 0
override fun iterator(): Iterator = listIterator()
override fun listIterator(): ListIterator = list.listIterator(1)
override fun listIterator(index: Int): ListIterator = list.listIterator(index + 1)
override fun subList(fromIndex: Int, toIndex: Int): List = 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): 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
Puede notar que las funciones en la sección después del comentario aún terminan haciendo una copia ansiosa. Solo hice esto por el bien de la simplicidad. Por el bien de la memoria, hice un lazy
tailList
propiedad
Todos podrían implementarse iterando sobre la colección manualmente, en lugar de hacer algún tipo de delegación. Si eso es lo que prefieres, estoy seguro de que puedes resolverlo.
Con eso, las propiedades de cabeza y cola se convierten en esto:
val List.tail: List
get() =
if(this.isEmpty())
throw IllegalStateException("Cannot get the tail of an empty List")
else
TailList(this)
val List.head: T
get() = this[0] // or first()
Si realmente lo necesita, puedo agregar una actualización para hacer que los últimos tres miembros funcionen para que no hagan copias ansiosas.
EDITAR: Nota: si siguió las convenciones que Kotlin ha seguido hasta ahora, no haría el List
La cola de ser perezoso, así, ya que todas sus funciones en List
hacer copias ansiosas. En cambio, especialmente si está usando head
y tail
para iterar recursivamente sobre una lista, vería si pudiera intentar esta idea de contenedor en Sequence
de alguna manera. Sequence
Todo el punto de existencia de ‘s es para el trabajo perezoso en las colecciones.
EDIT 2: Aparentemente, sublist() crea una vista y, por lo tanto, ya es perezoso. Esencialmente, le acabo de enseñar cómo crear la implementación para la sublista, excepto que la reduje a solo la cola.
Entonces, en ese caso, solo use sublist() para su función de cola.
Recuerda algo, que te concedemos esclarecer si topaste tu preocupación en el momento minucioso.