Kotlin From Scratch Ranges and Collections

Kotlin är ett modernt programmeringsspråk som kompilerar till Java bytecode. Det är gratis och öppen källkod, och lovar att göra kodning för Android ännu roligare.

I den föregående artikeln i denna serie lärde du dig om nullabilitet, loopar och förhållanden i Kotlin. I den här handledningen fortsätter vi att lära sig språket genom att titta på API-serier och samlingar i Kotlin.

1. Ranges

En serie i Kotlin är en unik typ som definierar ett startvärde och ett slutvärde. Med andra ord är det ett intervall mellan en start och ett slutvärde. Rang i Kotlin är stängda, vilket betyder att startvärdet och slutvärdet ingår i intervallet. 

Vi ska nu titta på olika sätt att skapa intervaller i Kotlin.

De ...  Operatör

val oneToFive = 1 ... 5

I koden ovan har vi skapat ett slutet intervall. Denna variabel oneToFive kommer att innehålla följande värden: 1, 2, 3, 4, 5. Vi kan slinga över det med hjälp av för slingkonstruktion.

för (n i oneToFive) print (n)

Koden ovan kan förkortas till:

för (n i 1 ... 5) utskrift (n)

Vi kan också skapa en rad olika tecken:

val aToZ = "a" ... "z"

Variabeln a till Z kommer att ha alla bokstäver i det engelska alfabetet.

De rangeTo () Fungera

De ... Operatören kan bytas ut med rangeTo () förlängningsfunktion för att skapa ett intervall. Till exempel kan vi också göra det här 1.rangeTo (5) och det skulle fortfarande ha samma resultat som att använda ...  operatör som diskuterats tidigare. 

val oneToFive: IntRange = 1.rangeTo (5)

De ner till() Fungera

Detta är en annan förlängningsfunktion som skapar ett intervall från ett givet nummer ner till en annan.

val fiveToOne = 5.downTo (1)

Vi kan ändra intervallet med hjälp av steg() fungera. Detta kommer att ändra deltaet mellan varje element i intervallet.

val oneToTenStep = 1 ... 10 steg 2 // 1, 3, 5, 7, 9

Koden ovan kommer att innehålla udda siffror mellan 1 och 10.

De i Operatör

De i operatör används för att se om ett värde är närvarande i ett visst intervall.

om (5 i 1 ... 10) skriv ut ("Ja 5 är i intervallet") // utskrifter "Ja 5 är i intervallet"

I koden ovan kontrollerade vi för att se om 5 ligger i intervallet 1 ... 10 med hjälp av i operatör. Vi kan också göra motsatsen genom att använda !n för att kontrollera om 5 inte ligger inom intervallet.

2. Samlingar

Samlingar används för att lagra grupper av relaterade objekt i minnet. I en samling kan vi hämta, lagra eller organisera objekten. Kotlin tillhandahåller sitt samlings API som ett standardbibliotek som byggts ovanpå Java Collections API. (Vi diskuterar gränssnitt i Kotlin i ett framtida inlägg.) 

Du bör notera att dessa gränssnitt är kopplade till deras genomförande vid sammanställningstiden. Du kan inte se källkoden för implementering i Kotlin, eftersom samlingarna faktiskt implementeras av standard Java-samlingar, t.ex. ArraylistKartorHashMapStällerHashSetLista och så vidare. För att verkligen förstå samlings API i Kotlin måste du vara bekant med dessa grundläggande klasser och gränssnitt i Java.

I det här avsnittet lär vi oss om Lista, Uppsättning och Karta samlingar i Kotlin. (Om du vill ha en uppdatering på arrays i Kotlin, vänligen besök den första handledningen i denna serie.) 

Kotlins samlingar ger oss möjlighet att uppnå mycket med bara en liten kod - till skillnad från Java, vilket tycks behöva mycket kod för att uppnå lite! Kotlin har två varianter av samlingar: mutable och immutable. En muterbar samling ger oss möjligheten att modifiera en samling genom att antingen lägga till, ta bort eller ersätta ett element. Immutabla samlingar kan inte modifieras och har inte dessa hjälpar metoder. 

Observera att tillägg, borttagning eller utbyte av ett element i en oföränderlig samling är möjlig via operatörsfunktioner (det kommer vi snart att få), men det kommer slutligen att skapa en ny samling.

De Iterable Gränssnitt

Kotlin Iterable gränssnittet ligger högst upp i samlingsklasshierarkin. Detta gränssnitt gör att samlingar kan representeras som en sekvens av element (som kan vara itererade över, naturligtvis). 

offentligt gränssnitt Iterable offentlig abstrakt operatör rolig iterator (): Iterator 

De Samling Gränssnitt

Kotlin Samling gränssnittet sträcker sig Iterable gränssnitt. De Samling gränssnittet är oföränderligt. Med andra ord har du skrivskyddad tillgång till samlingar. De Uppsättning och Lista gränssnitt (mer om dessa inom kort) i Kotlin utökar detta gränssnitt. 

Några av de funktioner och egenskaper som finns i Samling gränssnittet är:

  • storlek: Den här egenskapen returnerar storleken på samlingen.
  • är tom(): returnerar sant om samlingen är tom eller falsk på annat sätt. 
  • innehåller (element: E): returnerar sant om elementet som anges i argumentet är närvarande i samlingen.
  • containsAll (element: Collection): returnerar sant om elementet i samlingen passerat som argument finns i samlingen.  
offentligt gränssnitt Samling : Iterable offentliga valstorlek: Int public fun isEmpty (): Boolean public operator fun innehåller (element: @UnsafeVariance E): Boolean överstyrning roligt iterator (): Iterator allmänt roligt innehåller alla (element: samling<@UnsafeVariance E>): Booleska

De MutableIterable Gränssnitt

Detta gränssnitt i Kotlin ger oss en specialiserad, muterbar iterator från föräldern Iterable gränssnitt.

public interface MutableIterable : Iterable åsidosätta rolig iterator (): MutableIterator 

De MutableCollection Gränssnitt

De MutableCollection gränssnittet i Kotlin är ett specialiserat gränssnitt som gör att samlingar kan vara smidiga. Med andra ord, lägg till och ta bort operationer kan utföras på en given samling. Detta gränssnitt utökar både Samling gränssnitt och MutableIterable gränssnitt som redan diskuterats ovan. De MutableSet och MutableList gränssnitt (vi kommer snart till dem) i Kotlin utöka detta gränssnitt. Funktionerna i detta gränssnitt, förutom de som finns i föräldrarna, är:

  • lägg till (element: E): lägger till elementet som ett argument till samlingen och returnerar sant om det är framgångsrikt eller felaktigt om samlingen inte stöder dubbletter och elementet är redan närvarande.
  • ta bort (element: E): tar bort elementet som passerat som ett argument från samlingen. Returnerar sant om det är framgångsrikt eller falskt om det inte var närvarande i samlingen.
  • addAll (element: Samling): lägger till alla element i samlingen som skickas som argument till samlingen. Returnerar sant om det är framgångsrikt eller felaktigt om ingenting har lagts till.
  • removeAll (element: Collection): tar bort alla element som finns i samlingen som skickas som argument. Returnerar sant om det är framgångsrikt eller felaktigt om ingenting har tagits bort.
  • behållaAlla (element: samling): behåller endast de element som finns i de samlingar som överförs som argument. Returnerar sant om det är framgångsrikt eller felaktigt om inget behölls. 
  • klar(): tar bort alla element från denna samling.
offentligt gränssnitt MutableCollection : Samling, MutableIterable åsidosätta rolig iterator (): MutableIterator public fun add (element: E): Boolean public fun remove (element: E): Boolean public fun addAll (element: Collection): Booleskt offentligt roligt removeAll (elements: Collection): Booleskt offentligt roligt behållAlla (element: Samling): Booleskt offentligt roligt (): Enhet

Nu har du lärt dig om de bästa gränssnitten i kollektionsklasshierarkin i Kotlin, låt oss nu titta på hur Kotlin hanterar samlingar som Listor, uppsättningar och kartor i den återstående delen av handledningen.

listor

En lista är en beställd samling av element. Detta är en populär samling som används allmänt. Låt oss titta på olika sätt att skapa en lista i Kotlin.

Använda lista av() Fungera

I Kotlin kan vi skapa en oföränderlig (skrivskyddad) lista med lista av() hjälparfunktion från Kotlins standardbibliotek. Den här funktionen returnerar en Kotlin Lista gränssnittstyp.

var nummer: lista = listOf (1, 2, 3, 4, 5) var namn: Lista = listOf ("Chike", "Nnamdi", "Mgbemena") för (namn i namn) println (namn)

Att köra koden ovan kommer att skrivas ut: 

Chike Nnamdi Mgbemena

Dessutom kan vi överföra värden av olika typer till lista av() som argument och resultatet kommer fortfarande att fungera - det kommer att bli en lista med blandad typ. 

var listMixedTypes = listOf ("Chike", 1, 2.445, s)) // kommer fortfarande att sammanställa 

Använda emptyList () Fungera

Den här funktionen skapar bara en tom, oföränderlig lista och returnerar en Kotlin Lista gränssnittstyp.

val emptyList: List = emptyList() 

Använda listOfNotNull () Fungera

Den här funktionen skapar en ny oföränderlig lista som endast innehåller element som inte är noll. Observera att denna funktion returnerar en Kotlin Lista gränssnittstyp också.

val nonNullsList: Lista = listOfNotNull (2, 45, 2, null, 5, null)

De Lista gränssnittet från Kotlin standardbiblioteket utökar endast Samling gränssnitt. Med andra ord är dess enda förälder Samling gränssnitt. Det åsidosätter alla funktioner i modergränssnittet för att tillgodose sina speciella behov och definierar även sina egna funktioner, såsom:

  • få (index: Int): en funktionsoperatör som returnerar elementet vid det angivna indexet. 
  • indexOf (element: E): returnerar indexet för den första förekomsten av elementet som passerat som ett argument i listan, eller -1 om ingen hittas.
  • lastIndexOf (element: E): returnerar indexet för den sista förekomsten av elementet som passerat som ett argument i listan, eller -1 om ingen hittas. 
  • ListIterator (): returnerar en lista iterator över elementen i listan.
  • subList (fromIndex: Int, toIndex: Int): returnerar en lista som innehåller delen av listan mellan de angivna start- och slutindexen. 
println (names.size) // 3 println (names.get (0)) // "Chike" println (names.indexOf ("Mgbemena")) // 2 println (names.contains ("Nnamdi")) // 'Sann'

Använda arrayListOf () Fungera

Detta skapar en muterbar lista och returnerar en Java Arraylist typ.

val stringList: ArrayList = arrayListOf("Hej du där") 

Använda mutableListOf () Fungera

För att lägga till, ta bort eller ersätta värden i en lista måste vi göra listan till en variabel. Vi kan konvertera en oföränderlig lista till en mutabel genom att ringa funktionen toMutableList () på listan. Observera dock att den här metoden skapar en ny lista.

var mutableNames1 = names.toMutableList () mutableNames1.add ("Rut") // nu mutable och lagt till "Ruth" till listan

För att skapa en muterbar lista av en viss typ från början, t.ex.. Sträng, vi använder mutableListOf(), medan för blandade typer vi bara kan använda mutableListOf () funktion i stället.

// en mutabel lista av en viss typ, t.ex. String val mutableListNames: MutableList = mutableListOf("Josh", "Kene", "Sanya") mutableListNames.add ("Mary") mutableListNames.removeAt (1) mutableListNames [0] = "Oluchi" // ersätter elementet i index 0 med "Oluchi" // a mutabel lista över blandade typer val mutableListMixed = mutableListOf ("BMW", "Toyota", 1, 6,76, 'v')

Någon av dessa funktioner kommer att returnera a MutableList Kotlin gränssnittstyp. Detta gränssnitt utökar både MutableCollection och Lista gränssnitt som diskuterats tidigare i detta avsnitt. De MutableList gränssnittet lägger till metoder för hämtning eller substitution av ett objekt baserat på dess position: 

  • set (index: Int, element: E): ersätter ett element i listan med ett annat element. Detta returnerar elementet tidigare vid den angivna positionen.
  • lägg till (index: Int, element: E): infogar ett element vid det angivna indexet. 
  • removeAt (index: Int): blir av med elementet vid ett visst index. 
Val mutableListFood: MutableList = mutableListOf("Rice & stew", "Jollof rice", "Eba & Egusi", "Fried rice") mutableListFood.remove ("Fried rice") mutableListFood.removeAt (0) mutableListFood.set (0, "Beans") mutableListFood. lägg till (1, "Bröd & te") för (foodName i mutableListFood) println (foodName)

Om du kör koden ovan producerar vi följande resultat:

Bönor Bröd & te Eba & Egusi

Observera att alla dessa funktioner skapar en Java Arraylist bakom kulisserna.

Ställer

En uppsättning är en orörd uppsättning unika element. Med andra ord kan det inte ha några dubbletter! Låt oss titta på några av de olika sätten att skapa en uppsättning i Kotlin. Var och en av dessa skapar en annan datastruktur, som alla är optimerade för en viss typ av uppgift. 

Använda uppsättning av() Fungera

För att skapa en oföränderlig (skrivskyddad) uppsättning i Kotlin kan vi använda funktionen uppsättning av(), som returnerar en Kotlin Uppsättning gränssnittstyp. 

// skapar en oföränderlig uppsättning blandade typer val mixedTypesSet = setOf (2, 4.454, "how", "far", "c") // kommer att kompilera var intSet: Set = setOf (1, 3, 4) // Endast heltalstyper tillåtna

Observera att Kotlin Uppsättning gränssnittet utökar endast Kotlin Samling gränssnittet och överstyrar alla egenskaper som finns i sin förälder.

Använda hashSetOf () Fungera 

Använda hashSetOf () funktion skapar en Java HashSet samling som lagrar element i ett hashbord. Eftersom denna funktion returnerar en Java HashSet typ kan vi lägga till, ta bort eller rensa element i uppsättningen. Med andra ord är det omöjligt. 

val intsHashSet: java.util.HashSet = hashSetOf (1, 2, 6, 3) intsHashSet.add (5) intsHashSet.remove (1) 

Använda sortedSetOf () Fungera

Använda sortedSetOf () funktion skapar en Java TreeSet samling bakom kulisserna, som beställer element baserat på deras naturliga beställning eller av en jämförare. Denna uppsättning är också mutabel.

val intsSortedSet: java.util.TreeSet = sortedSetOf (4, 1, 7, 2) intsSortedSet.add (6) intsSortedSet.remove (1) intsSortedSet.clear ()

Använda linkedSetOf () Fungera

Den här funktionen returnerar en Java LinkedHashSet typ. Denna muterbara uppsättning upprätthåller en länkad lista över poster i uppsättningen, i den ordning i vilken de infördes. 

val intsLinkedHashSet: java.util.LinkedHashSet = linkedSetOf (5, 2, 7, 2, 5) // 5, 2, 7 intsLinkedHashSet.add (4) intsLinkedHashSet.remove (2) intsLinkedHashSet.clear ()

Använda mutableSetOf () Fungera

Vi kan använda mutableSetOf () för att skapa en muterbar uppsättning. Den här funktionen returnerar en Kotlin MutableSet gränssnittstyp. Bakom kulisserna skapar denna funktion helt enkelt en Java LinkedHashSet.  

// skapar en variabel uppsättning av int typer bara val intsMutableSet: MutableSet = mutableSetOf (3, 5, 6, 2, 0) intsMutableSet.add (8) intsMutableSet.remove (3)

De MutableSet gränssnittet utökar både MutableCollection och den Uppsättning gränssnitt. 

Kartor

Kartor associerar nycklar till värden. Nycklarna måste vara unika, men de tillhörande värdena behöver inte vara. På så sätt kan varje nyckel användas för att unikt identifiera det tillhörande värdet, eftersom kartan ser till att du inte kan ha dubbla nycklar i samlingen. Bakom kulisserna använder Kotlin Java Karta samling för att genomföra sin kartsamlingstyp.

Använda karta över() Fungera

Att skapa en oföränderlig eller skrivskyddad Karta samling i Kotlin använder vi karta över() fungera. Vi skapar en karta med denna funktion genom att ge den en lista med par. Det första värdet är nyckeln och den andra är värdet. Om du ringer till den här funktionen returneras en Kotlin Karta gränssnittstyp.

val callingCodesMap: Karta = mapOf (234 till "Nigeria", 1 till "USA", 233 till "Ghana") för ((nyckel, värde) i callingCodesMap) println ("$ nyckeln är anropskoden för $ värde") Skriv ut (callingCodesMap [234]) // Nigeria

Om du kör koden ovan kommer du att producera resultatet: 

234 är anropskoden för Nigeria 1 är anropskoden för USA 233 är anropskoden för Ghana

Till skillnad från Lista och Uppsättning gränssnitt i Kotlin som sträcker sig Samling gränssnitt, Karta gränssnittet sträcker sig inte alls. Några av de egenskaper och funktioner som finns i detta gränssnitt är:

  • storlek: Den här egenskapen returnerar storleken på kartsamlingen.
  • är tom(): returnerar sant om kartan är tom eller falsk på annat sätt.
  • innehållerKey (nyckel: K): returnerar sant om kartan innehåller nyckeln i argumentet. 
  • innehållerValue (värde: V): returnerar sant om kartan kartlägger en eller flera nycklar till det värde som passerat som ett argument.
  • få (nyckel: K): returnerar värdet som matchar den angivna nyckeln eller "null" om ingen hittas. 
  • nycklar: Den här egenskapen returnerar en oföränderlig Uppsättning av alla nycklar i kartan.
  • värden: returnerar en oföränderlig Samling av alla värden i kartan.

Använda mutableMapOf () Fungera

De mutableMapOf () funktionen skapar en muterbar karta för oss så att vi kan lägga till och ta bort element i kartan. Detta returnerar en Kotlin MutableMap gränssnittstyp.

Val currenciesMutableMap: MutableMap = mutableMapOf ("Naira" till "Nigeria", "Dollars" till "USA", "Pounds" till "UK") println ("Länder är $ currenciesMutableMap.values") // Länder är [Nigeria, USA, Storbritannien ] println ("Valutor är $ currenciesMutableMap.keys") // Valutor är [Naira, Dollars, Pounds] currenciesMutableMap.put ("Cedi", "Ghana") valutorMutableMap.remove ("Dollars")

De MutableMap gränssnittet sträcker inte ut MutableCollection gränssnitt; det är bara förälder är Karta gränssnitt. Det strider mot nycklaranteckningar och värden egenskaper från modergränssnittet för att omdefiniera dem. Här är några av de extra funktionerna som finns i MutableMap gränssnitt:

  • put (tangent: K, värde: V): sätter in nyckeln, värdeparet i kartan. Detta kommer att returnera det tidigare värdet kopplat till nyckeln eller noll om nyckeln inte tidigare användes. 
  • ta bort (tangent: K): tar bort nyckeln och dess länkade värde från kartan. 
  • sätt alla(från: Karta): uppdaterar kartan med alla data från den angivna kartan. Nya nycklar läggs till och befintliga nycklar uppdateras med nya värden. 
  • klar(): tar bort alla element från kartan. 

Vi kan få värdet för en nyckel med hjälp av skaffa sig() fungera. Vi kan också använda kvadratkonsol notation som en genväg för skaffa sig()

print (currenciesMutableMap.get ("Nigeria")) // kommer att skriva ut Naira-utskrift (currenciesMutableMap ["Nigeria"]) // kommer att skriva ut Naira

Använda hashMapOf () Fungera

Med hjälp av denna funktion returneras en Java HashMap typ som är mutable. De HashMap klassen använder ett hashbord för att implementera Java Karta gränssnitt.  

valpersonerHashMap: java.util.HashMap = hashMapOf (1 till "Chike", 2 till "John", 3 till "Emeka") personsHashMap.put (4, "Chuka") personerHashMap.remove (2) print (personsHashMap [1]) // kommer att skriva ut Chike

Använda linkedHashMap () Fungera

Den här funktionen returnerar en Java LinkedHashMap typ som är mutable. De LinkedHashMap klassen utökar Java HashMap och upprätthåller en länkad lista över posterna i kartan i den ordning de infördes i. 

val postkodHashMap: java.util.LinkedHashMap = "NG" till "Nigeria", "AU" till "Australien", "CA" till "Kanada") postCodesHashMap.put ("NA", "Namibia") postkoderHashMap.remove ("AU") postkoderHashMap.get ("CA") // Kanada

Använda sortedMapOf () Fungera

Den här funktionen returnerar en Java SortedMap typ som är muterbar. Java SortedMap klassen ser att posterna i kartan bibehålls i en stigande nyckelordning.

Val PersonsSortedMap: java.util.SortedMap = sortedMapOf (2 till "Chike", 1 till "John", 3 to "Emeka") personsSortedMap.put (7, "Adam") personsSortedMap.remove (3)

Kom ihåg att genomförandet av dessa samlingsgränssnitt i Kotlin händer vid sammanställningstiden.

Samlingar Funktionsfunktioner

Kotlin ger oss många användbara operatörsfunktioner som kallas förlängningsfunktioner som kan åberopas på samlingar. Låt oss ta en titt på några av de mest användbara.

De sista() Fungera

Den här operatörsfunktionen returnerar det sista elementet i en samling, till exempel en lista eller en uppsättning. Vi kan också leverera ett predikat för att söka inom en delmängd av element.

val stringList: List = listOf ("in", "the", "club") print (stringList.last ()) // kommer att skriva ut "club" // givet ett predikatutskrift (stringList.last it.length == 3) / / kommer att skriva ut "valet intSet: Set = setOf (3, 5, 6, 6, 6, 3) print (intSet.last ()) // kommer att skriva ut 6

De först() Fungera

Den här operatörsfunktionen returnerar det första elementet när det kallas på en samling, till exempel en lista eller en uppsättning. Om ett predikat ges, använder det sedan predikatet för att begränsa operationen till en delmängd av element.

print (stringList.first ()) // kommer att skriva ut "in" print (intSet.first ()) // kommer att skriva ut 3

De max () Fungera

Inbjuder denna operatörsfunktion på en samling, som en lista eller uppsättning, returnerar det största elementet, eller null om inget större element hittas.

val intList: Lista = listOf (1, 3, 4) print (intList.max ()) // kommer att skriva ut 4 utskrift (intSet.max ()) // kommer att skrivas ut 6 

De släppa() Fungera

Ringa denna operatörsfunktion returnerar en ny lista eller uppsättning som innehåller alla element utom de första n-elementen.

print (stringList.drop (2)) // kommer skriva ut "club"

De plus() Fungera

Den här operatörsfunktionen returnerar en samling som innehåller alla element i originalet och sedan det angivna elementet om det inte redan finns i samlingen. Detta kommer att sluta skapa en ny lista istället för att ändra listan.

skriv ut (intList.plus (6)) // kommer att skriva ut [1, 3, 4, 6]

De minus() Fungera

Det motsatta av plus() funktionen är minus() fungera. Den returnerar en samling som innehåller alla element i den ursprungliga uppsättningen utom det angivna elementet. Detta slutar också att skapa en ny lista istället för att ändra listan.

skriv ut (intList.minus (3)) // kommer att skriva ut [1, 4]

De medel() Fungera

Om du ringer till den här operatörsfunktionen returneras ett genomsnittligt antal element i samlingen.

skriv ut (intList.average ()) // kommer skriva ut 2.6666666666666665

De flesta av dessa anknytningsfunktioner finns i Kotlins samlingsstandardbibliotek. Du rekommenderas att kolla dokumentationen för att lära sig om de andra.

Slutsats

I denna handledning lärde du dig om API-sortimentet och samlingar i Kotlins programmeringsspråk. I nästa handledning i Kotlin From Scratch-serien introduceras du i funktioner i Kotlin. Ses snart!

För att lära mig mer om Kotlins språket rekommenderar jag att du besöker Kotlins dokumentation. Eller kolla in några av våra andra Android App-utvecklingsposter här på Envato Tuts!