Overzicht van Kotlin Collections API

1. Overzicht

In deze korte tutorial introduceren we de Kotlin's Collections API, en we bespreken de verschillende soorten verzamelingen in Kotlin en enkele veelvoorkomende bewerkingen op verzamelingen.

2. Verzameling versus veranderlijke verzameling

Laten we eerst eens kijken naar verschillende soorten collecties in Kotlin. We zullen zien hoe u de basistypen van verzamelingen kunt initialiseren.

De Verzameling interface ondersteunt alleen-lezen methoden terwijl MutableCollection ondersteuning voor lees- / schrijfmethoden.

2.1. Lijst

We kunnen een eenvoudig alleen-lezen Lijst met behulp van methode lijst van() en lezen-schrijven MutableList gebruik makend van mutableListOf ():

val theList = listOf ("een", "twee", "drie") val theMutableList = mutableListOf ("een", "twee", "drie")

2.2. Set

Op dezelfde manier kunnen we een alleen-lezen Set met behulp van methode setOf () en lezen-schrijven MutableSet gebruik makend van mutableSetOf ():

val theSet = setOf ("een", "twee", "drie") val theMutableSet = mutableSetOf ("een", "twee", "drie")

2.3. Kaart

We kunnen ook een alleen-lezen Kaart met behulp van methode kaart van() en lezen-schrijven MutableMap gebruik makend van mutableMapOf ():

val theMap = mapOf (1 tot "één", 2 tot "twee", 3 tot "drie") val theMutableMap = mutableMapOf (1 tot "één", 2 tot "twee", 3 tot "drie")

3. Handige operators

De Collections API van Kotlin is veel rijker dan degene die we in Java kunnen vinden - het wordt geleverd met een reeks overbelaste operators.

3.1. De "in" Operator

We kunnen de uitdrukking 'x in verzameling”Die vertaald kan worden naar collectie. bevat (x):

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

3.2. De “+” Operator

We kunnen een element of hele verzameling naar een ander met behulp van de "+" -operator:

@Test plezier 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 ("twee")) assertTrue (resultList.contains ("vijf"))}

3.3. De “-“ Operator

Evenzo kunnen we een element of meerdere elementen verwijderen met de operator "-":

@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

Ten slotte zullen we enkele veelgebruikte methoden voor het verzamelen onderzoeken. Als we in Java geavanceerde methoden wilden gebruiken, zouden we Stroom API.

In Kotlin kunnen we vergelijkbare methoden vinden die beschikbaar zijn in de Collections API.

4.1. Snijden

We kunnen een sublijst krijgen van een gegeven Lijst:

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

4.2. Verwijderen

We kunnen eenvoudig alle null-waarden verwijderen uit een Lijst:

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

4.3. Filteren

We kunnen collectie-items eenvoudig filteren met behulp van filter(), die op dezelfde manier werkt als de filter() methode uit Java Stroom API:

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

4.4. Laten vallen

We kunnen de eerste N items laten vallen:

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

We kunnen de eerste paar items laten vallen als ze aan de gegeven voorwaarde voldoen:

@Test plezier whenDropFirstItemsBasedOnCondition_thenRemoved () {val theList = listOf ("één", "twee", "drie", "vier") val resultList = theList.dropWhile {it.length <4} assertEquals (2, resultList.size) assertFalse (resultList.contains ("één")) assertFalse (resultList.contains ("twee"))}

4.5. Groepering

We kunnen elementen groeperen:

@Test plezier 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] !!. bevat (5))}

4.6. In kaart brengen

We kunnen alle elementen in kaart brengen met behulp van de aangeboden functie:

@Test leuk 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])}

We kunnen gebruiken flatMap () om geneste verzamelingen af ​​te vlakken. Hier zijn we aan het converteren Snaren naar List en vermijden om te eindigen met Lijst:

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

4.7. Vermindering

We kunnen optreden vouwen / verkleinen operatie:

@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

Om een ​​verzameling op te splitsen in brokken van een bepaalde grootte, kunnen we de in stukken gesneden () methode:

@Test leuk 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]). bevat (3, 4) assertThat (chunked.last ()). bevat (5)}

Omdat de collectie vijf elementen heeft, is de in stukken gesneden (2) method call retourneert twee verzamelingen met elk twee elementen en één verzameling met één element.

Het is ook mogelijk om elk brok aan iets anders toe te wijzen nadat de verzameling is opgedeeld:

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

Nadat we chunks van maat 3 hebben gemaakt, converteren we elk chunk naar een door komma's gescheiden string.

4.9. Windowing

De met vensters () functie retourneert een lijst met elementbereiken door een schuifvenster van een bepaalde grootte over een verzameling elementen te verplaatsen.

Laten we eens kijken hoe we dit beter kunnen begrijpen met raam (3) werkt aan een verzameling van 6 elementen:

In eerste instantie is de venstergrootte 3, daarom zou de eerste lijst 1, 2 en 3 bevatten. Vervolgens schuift het schuifvenster een element verder:

Het schuifvenster beweegt naar voren totdat het er niet in slaagt een andere lijst van de opgegeven grootte te maken:

Deze reeks overgangen manifesteert zich in de Kotlin-code als:

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

Standaard schuift het schuifvenster elke keer een stap verder. We kunnen dat natuurlijk veranderen door een aangepaste stapwaarde door te geven:

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

De met vensters () -functie maakt standaard altijd en alleen bereiken van de opgegeven grootte. Om dat te veranderen, kunnen we de gedeeltelijke Windows parameter naar waar:

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

Net als bij de in stukken gesneden () functie, is het mogelijk om elk bereik aan iets anders toe te wijzen:

@Test leuk 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. Conclusie

We hebben de Collections API van Kotlin en enkele van de meest interessante methoden onderzocht.

En, zoals altijd, is de volledige broncode te vinden op GitHub.