Übersicht über die Kotlin Collections API

1. Übersicht

In diesem kurzen Tutorial stellen wir die Sammlungs-API von Kotlin vor und erläutern die verschiedenen Sammlungstypen in Kotlin sowie einige allgemeine Vorgänge für Sammlungen.

2. Sammlung vs. veränderliche Sammlung

Schauen wir uns zunächst verschiedene Arten von Sammlungen in Kotlin an. Wir werden sehen, wie die grundlegenden Arten von Sammlungen initialisiert werden.

Die Collection- Schnittstelle unterstützt schreibgeschützte Methoden, während MutableCollection Lese- / Schreibmethoden unterstützt.

2.1. Liste

Wir können eine einfache schreibgeschützte Liste mit der Methode listOf () erstellen und MutableList mit mutableListOf () schreibgeschützt machen :

val theList = listOf("one", "two", "three") val theMutableList = mutableListOf("one", "two", "three")

2.2. einstellen

Ebenso können wir mit der Methode setOf () ein schreibgeschütztes Set erstellen und mit mutableSetOf () MutableSet schreibgeschützt machen :

val theSet = setOf("one", "two", "three") val theMutableSet = mutableSetOf("one", "two", "three")

2.3. Karte

Wir können auch eine schreibgeschützte Map mit der Methode mapOf () erstellen und MutableMap mit mutableMapOf () schreibgeschützt schreiben :

val theMap = mapOf(1 to "one", 2 to "two", 3 to "three") val theMutableMap = mutableMapOf(1 to "one", 2 to "two", 3 to "three")

3. Nützliche Operatoren

Kotlins Sammlungs-API ist viel umfangreicher als die in Java - sie enthält eine Reihe überladener Operatoren.

3.1. Der " in" -Operator

Wir können den Ausdruck " x in Sammlung " verwenden, der in collection.contains (x) übersetzt werden kann :

@Test fun whenSearchForExistingItem_thenFound () { val theList = listOf("one", "two", "three") assertTrue("two" in theList) }

3.2. Der Operator "+"

Wir können ein Element oder eine gesamte Sammlung mit dem Operator "+" zu einem anderen Element:

@Test fun whenJoinTwoCollections_thenSuccess () { val firstList = listOf("one", "two", "three") val secondList = listOf("four", "five", "six") val resultList = firstList + secondList assertEquals(6, resultList.size) assertTrue(resultList.contains("two")) assertTrue(resultList.contains("five")) }

3.3. Der Operator „-“

Ebenso können wir ein Element oder mehrere Elemente mit dem Operator "-" entfernen:

@Test fun whenExcludeItems_thenRemoved () { val firstList = listOf("one", "two", "three") val secondList = listOf("one", "three") val resultList = firstList - secondList assertEquals(1, resultList.size) assertTrue(resultList.contains("two")) }

4. Andere Methoden

Schließlich werden wir einige gängige Methoden für die Sammlung untersuchen. Wenn wir in Java erweiterte Methoden nutzen möchten, müssen wir die Stream- API verwenden.

In Kotlin finden wir ähnliche Methoden in der Collections-API.

4.1. Schneiden

Wir können eine Unterliste aus einer gegebenen Liste erhalten:

@Test fun whenSliceCollection_thenSuccess () { val theList = listOf("one", "two", "three") val resultList = theList.slice(1..2) assertEquals(2, resultList.size) assertTrue(resultList.contains("two")) }

4.2. Entfernen

Wir können leicht alle Nullen aus einer Liste entfernen :

@Test fun whenFilterNullValues_thenSuccess () { val theList = listOf("one", null, "two", null, "three") val resultList = theList.filterNotNull() assertEquals(3, resultList.size) }

4.3. Filtern

Wir können Sammlungselemente einfach mit filter () filtern , das ähnlich wie die filter () -Methode der Java Stream- API funktioniert :

@Test fun whenFilterNonPositiveValues_thenSuccess () { val theList = listOf(1, 2, -3, -4, 5, -6) val resultList = theList.filter{ it > 0} assertEquals(3, resultList.size) assertTrue(resultList.contains(1)) assertFalse(resultList.contains(-4)) }

4.4. Fallenlassen

Wir können die ersten N Gegenstände fallen lassen:

@Test fun whenDropFirstItems_thenRemoved () { val theList = listOf("one", "two", "three", "four") val resultList = theList.drop(2) assertEquals(2, resultList.size) assertFalse(resultList.contains("one")) assertFalse(resultList.contains("two")) }

Wir können die ersten paar Gegenstände fallen lassen, wenn sie die gegebene Bedingung erfüllen:

@Test fun whenDropFirstItemsBasedOnCondition_thenRemoved () { val theList = listOf("one", "two", "three", "four") val resultList = theList.dropWhile{ it.length < 4 } assertEquals(2, resultList.size) assertFalse(resultList.contains("one")) assertFalse(resultList.contains("two")) }

4.5. Gruppierung

Wir können Elemente gruppieren:

@Test fun whenGroupItems_thenSuccess () { val theList = listOf(1, 2, 3, 4, 5, 6) val resultMap = theList.groupBy{ it % 3} assertEquals(3, resultMap.size) assertTrue(resultMap[1]!!.contains(1)) assertTrue(resultMap[2]!!.contains(5)) }

4.6. Kartierung

Wir können alle Elemente mit der bereitgestellten Funktion abbilden:

@Test fun whenApplyFunctionToAllItems_thenSuccess () { val theList = listOf(1, 2, 3, 4, 5, 6) val resultList = theList.map{ it * it } assertEquals(4, resultList[1]) assertEquals(9, resultList[2]) }

Wir können flatMap () verwenden , um verschachtelte Sammlungen zu reduzieren . Hier konvertieren wir Strings zu L ist und die Vermeidung von mit enden Liste ::

@Test fun whenApplyMultiOutputFunctionToAllItems_thenSuccess () { val theList = listOf("John", "Tom") val resultList = theList.flatMap{ it.toLowerCase().toList() } assertEquals(7, resultList.size) }

4.7. Die Ermäßigung

Wir können Falt- / Reduktionsvorgänge durchführen:

@Test fun whenApplyFunctionToAllItemsWithStartingValue_thenSuccess () { val theList = listOf(1, 2, 3, 4, 5, 6) val finalResult = theList.fold(0, {acc, i -> acc + (i * i)}) assertEquals(91, finalResult) }

4.8. Chunking

Um eine Sammlung in Blöcke einer bestimmten Größe zu unterteilen, können Sie die Methode chunked () verwenden:

@Test fun whenApplyingChunked_thenShouldBreakTheCollection() { val theList = listOf(1, 2, 3, 4, 5) val chunked = theList.chunked(2) assertThat(chunked.size).isEqualTo(3) assertThat(chunked.first()).contains(1, 2) assertThat(chunked[1]).contains(3, 4) assertThat(chunked.last()).contains(5) }

Since the collection has five elements, the chunked(2) method call returns two collections with two elements each and one single-element collection.

It's also possible to map each chunk to something else after breaking up the collection:

@Test fun whenApplyingChunkedWithTransformation_thenShouldBreakTheCollection() { val theList = listOf(1, 2, 3, 4, 5) val chunked = theList.chunked(3) { it.joinToString(", ") } assertThat(chunked.size).isEqualTo(2) assertThat(chunked.first()).isEqualTo("1, 2, 3") assertThat(chunked.last()).isEqualTo("4, 5") }

After creating chunks of size 3, we convert each chunk to a comma-separated string.

4.9. Windowing

The windowed() function returns a list of element ranges by moving a sliding window of a given size over a collection of elements.

In order to better understand this, let's see how windowed(3) works on a collection of 6 elements:

At first, the window size is 3, therefore the first list would contain 1, 2, and 3. Then the sliding window moves one element further:

Das Schiebefenster bewegt sich vorwärts, bis keine weitere Liste mit der angegebenen Größe erstellt werden kann:

Diese Folge von Übergängen manifestiert sich im Kotlin-Code als:

@Test fun whenApplyingWindowed_thenShouldCreateSlidingWindowsOfElements() { val theList = (1..6).toList() val windowed = theList.windowed(3) assertThat(windowed.size).isEqualTo(4) assertThat(windowed.first()).contains(1, 2, 3) assertThat(windowed[1]).contains(2, 3, 4) assertThat(windowed[2]).contains(3, 4, 5) assertThat(windowed.last()).contains(4, 5, 6) }

Standardmäßig bewegt sich das Schiebefenster jedes Mal einen Schritt weiter. Wir können dies natürlich ändern, indem wir einen benutzerdefinierten Schrittwert übergeben:

@Test fun whenApplyingWindowedWithTwoSteps_thenShouldCreateSlidingWindowsOfElements() { val theList = (1..6).toList() val windowed = theList.windowed(size = 3, step = 2) assertThat(windowed.size).isEqualTo(2) assertThat(windowed.first()).contains(1, 2, 3) assertThat(windowed.last()).contains(3, 4, 5) }

Die Funktion windowed () erstellt standardmäßig immer und nur Bereiche mit der angegebenen Größe. Um dies zu ändern, können wir den Parameter partitionWindows auf true setzen :

@Test fun whenApplyingPartialWindowedWithTwoSteps_thenShouldCreateSlidingWindowsOfElements() { val theList = (1..6).toList() val windowed = theList.windowed(size = 3, step = 2, partialWindows = true) assertThat(windowed.size).isEqualTo(3) assertThat(windowed.first()).contains(1, 2, 3) assertThat(windowed[1]).contains(3, 4, 5) assertThat(windowed.last()).contains(5, 6) }

Ähnlich wie bei der Funktion chunked () ist es möglich, jeden Bereich einem anderen Element zuzuordnen:

@Test fun whenApplyingTransformingWindows_thenShouldCreateSlidingWindowsOfElements() { val theList = (1..6).toList() val windowed = theList.windowed(size = 3, step = 2, partialWindows = true) { it.joinToString(", ") } assertThat(windowed.size).isEqualTo(3) assertThat(windowed.first()).isEqualTo("1, 2, 3") assertThat(windowed[1]).isEqualTo("3, 4, 5") assertThat(windowed.last()).isEqualTo("5, 6") }

5. Schlussfolgerung

Wir haben Kotlins Sammlungs-API und einige der interessantesten Methoden untersucht.

Und wie immer finden Sie den vollständigen Quellcode auf GitHub.