Java týden
30 % bodů zdarma na online výuku díky naší Slevové akci!
Pouze tento týden sleva až 80 % na e-learning týkající se Javy.

Lekce 7 - Pole v Kotlin

V minulé lekci kurzu, Typový systém: Null safety v Kotlin, jsme se naučili používat nullovatelné typy.

Dnes si v Kotlin tutoriálu představíme datovou strukturu pole a vyzkoušíme si, co všechno umí.

Pole

Představme si, že chceme uložit nějaké údaje o více prvcích. Např. chceme v paměti uchovávat 10 čísel, políčka šachovnice nebo jména 50 uživatelů. Asi vám dojde, že v programování bude nějaká lepší cesta, než začít bušit proměnné uzivatel1, uzivatel2, ... až uzivatel50. Nehledě na to, že jich může být třeba 1000. A jak by se v tom potom hledalo? Brrr, takhle ne :)

Pokud potřebujeme uchovávat větší množství proměnných stejného typu, tento problém nám řeší pole. Můžeme si ho představit jako řadu přihrádek, kde v každé máme uložený jeden prvek. Přihrádky jsou očíslované tzv. indexy, první má index 0.

Struktura pole v Kotlin

(Na obrázku je vidět pole osmi čísel)

Programovací jazyky se velmi liší v tom, jak s polem pracují. V některých jazycích (zejména starších, kompilovaných) nebylo možné za běhu programu vytvořit pole s dynamickou velikostí (např. mu dát velikost dle nějaké proměnné). Pole se muselo deklarovat s konstantní velikostí přímo ve zdrojovém kódu. Toto se obcházelo tzv. pointery a vlastními datovými strukturami, což často vedlo k chybám při manuální správě paměti a nestabilitě programu (např. v C++). Naopak některé interpretované jazyky umožňují nejen deklarovat pole s libovolnou velikostí, ale dokonce tuto velikost na již existujícím poli měnit (např. PHP). Kotlin se řadí k těm moderním, nemusíte se starat o velikost polí (dokonce ji ani nemůžete pevně zadat) a přidávat prvky můžete i do již vytvořeného pole.

Pole deklarujeme pomocí funkce arrayOf():

var pole = arrayOf<Int>()

Výraz pole je samozřejmě název naší proměnné. Nyní jsme vytvořili prázdné pole čísel typu Int.

Nové prvky do pole nejdříve přidáme operátorem +=. V našem případě za něj uvedeme přidávané číslo jako Int, který se uloží na konec pole:

var pole = arrayOf<Int>()
pole += 34

Do pole můžeme takto přidat i další pole stejného typu (tedy typu Int v našem případě), jehož prvky se do pole přidají.

K prvkům pole přistupujeme přes hranatou závorku, kam uvedeme index prvku. Můžeme to udělat samozřejmě pouze tehdy, když prvek na daném indexu existuje. Zkusme si to:

var pole = arrayOf<Int>()
pole += 34
print(pole[0])

Vypsali jsme prvek na indexu 0, tedy první, jelikož jsou indexy od nuly. Na výstupu opravdu vidíme číslo 34, které je tam uložené:

34
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Plnit pole takto ručně by bylo příliš pracné, použijeme cyklus a naplníme si pole čísly od 1 do 10. K naplnění použijeme for cyklus:

var pole = arrayOf<Int>()
for (i in 1..10) {
    pole += i
}

Abychom celé pole vypsali, můžeme za předchozí kód připsat:

for (i in pole) {
    print("$i ")
}

Nyní už je lépe vidět síla for cyklu v Kotlin. Stačí za in místo definované řady čísel vložit pole a cyklus projde všechny prvky. V těle cyklu k nim poté můžeme přistupovat a např. je vypsat:

1 2 3 4 5 6 7 8 9 10

Pole má vlastnost size, kde je uložen počet jeho prvků.

Pole samozřejmě můžeme naplnit ručně a to i bez toho, abychom dosazovali postupně do každého indexu. Použijeme k tomu funkci arrayOf() a do závorek napíšeme prvky, které oddělujeme čárkou. Tentokrát si zkusíme vytvořit pole textových řetězců:

val simpsonovi = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie")

Protože nyní nechceme, aby nám někdo obsah pole měnil, deklarujeme ho pomocí val a tím se pole stává konstantní. Vynechali jsme upřesnění typu, Kotlin z prvků totiž snadno pozná, že jde o pole řetězců (String). Samozřejmě nám ale nic nebrání typ uvést:

val simpsonovi: Array<String> = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie")

Pole často slouží k ukládání mezivýsledků, které se potom dále v programu používají. Když potřebujeme nějaký výsledek 10x, tak jej nebudeme 10x počítat, ale spočítáme jej jednou a uložíme do pole, odtud poté daný výsledek jen načteme.

Metody pole

Na polích nám Kotlin poskytuje pomocné metody pro práci s nimi. Pojďme se na ně podívat:

sort() a sorted()

Jak již název napovídá, metody nám pole seřadí. Metoda sort() seřadí již existující pole (takže musí být deklarované pomocí var) a sorted() nám vrátí nové setříděné pole, takže ho nesmíte zapomenout přiřadit do proměnné. Metody jsou dokonce tak chytré, že pracují podle toho, co máme v poli uložené. Řetězce třídí podle abecedy, čísla podle velikosti. Zkusme si setřídit a vypsat naši rodinku Simpsnů:

val simpsonovi: Array<String> = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie")
simpsonovi.sort()
for (simpson in simpsonovi) {
    println(simpson)
}

Výsledek:

Bart
Homer
Lisa
Marge
Meggie

A způsob seřazení pomocí metody sorted():

val simpsonovi: Array<String> = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie")

val simpsonovi_sorted = simpsonovi.sortedArray()
for (simpson in simpsonovi_sorted) {
    println(simpson)
}
Bart
Homer
Lisa
Marge
Meggie

Zkuste si vytvořit pole čísel a vyzkoušejte si, že to opravdu funguje i pro ně.

reverse() a reversedArray()

Tyto metody nám pole otočí (první prvek bude jako poslední atp.). Princip je opět stejný jako u třídění. Metoda reverse() otočí existující pole, reversedArray() nám potom otočené pole vrátí. Toho můžeme využít např. pro třídění pozpátku:

val simpsonovi: Array<String> = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie")
simpsonovi.sort()
simpsonovi.reverse()
for (simpson in simpsonovi) {
    println(simpson)
}

Výsledek:

Meggie
Marge
Lisa
Homer
Bart

indexOf()

Metoda nám najde první výskyt daného prvku v poli a vrátí jeho index jako Int. Může se stát, že prvek v poli není, v takovém případě metoda vrátí -1. Vytvoříme si jednoduchý program, který bude předpokládat, že Simpsni jsou v poli seřazení podle oblíbenosti. Když uživatel nějakého zadá, vypíšeme mu kolikátý je nebo že v poli není.

val simpsonovi = arrayOf("Homer", "Marge", "Bart", "Lisa", "Meggie")
println("Ahoj, zadej svého oblíbeného Simpsna (z rodiny Simpsnů): ")
val simpson = readLine()!!
val pozice = simpsonovi.indexOf(simpson)
if (pozice != -1) {
    println("Jo, to je můj ${pozice + 1}. nejoblíbenější Simpson!")
} else {
    println("Hele, tohle není Simpson!")
}

Výsledek:

Ahoj, zadej svého oblíbeného Simpsna (z rodiny Simpsnů):
Homer
Jo, to je můj 1. nejoblíbenější Simpson!

size

size jsme si již zmínili, obsahuje počet prvků v poli. Není metodou, ale vlastností, nepíší se za ni tedy závorky ().

isEmpty()

Jak asi tušíte, tato metoda vrátí true, pokud je naše pole prázdné. Její použití je čitelnější, než se ptát pomocí pole.size == 0. Z kódu je hned jasné, že nás zajímá možnost když je pole prázdné.

min() a max()

Matematické metody, vracející nejmenší prvek (min()) a největší prvek (max()) v poli. Výsledek vrátí jako nullovatelný typ, pro případ, že by pole bylo prázdné.

first() a last()

Již podle názvu vlastnosti vrátí první a poslední prvek. Návratové hodnoty jsou opět nullable.

contains()

Metoda vrací true/false podle toho, zda se prvek uvedený v parametru metody v daném poli nachází.

To by pro dnešek stačilo, můžete si s polem hrát.

V následujícím cvičení, Řešené úlohy k 7. lekci Kotlin, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Stáhnout

Staženo 151x (16.5 kB)

 

Předchozí článek
Typový systém: Null safety v Kotlin
Všechny články v sekci
Základní konstrukce jazyka Kotlin
Článek pro vás napsal Samuel Kodytek
Avatar
Jak se ti líbí článek?
3 hlasů
Autor se věnuje všem jazykům okolo JVM. Rád pomáhá lidem, kteří se zajímají o programování. Věří, že všichni mají šanci se naučit programovat, jen je potřeba prorazit tu bariéru, který se říká lenost.
Aktivity (11)

 

 

Komentáře
Zobrazit starší komentáře (8)

Avatar
Vojta Opravil:19. června 12:22

Co dělá vlastnost** size** ??

 
Odpovědět
19. června 12:22
Avatar
Alesh
Překladatel
Avatar
Odpovídá na Vojta Opravil
Alesh:19. června 12:26

Zkus si ten článek přečíst. ;-)

size jsme si již zmínili, obsahuje (vrací) počet prvků v poli.

 
Odpovědět
19. června 12:26
Avatar
Odpovídá na Alesh
Vojta Opravil:19. června 12:39

To jsem si přečetl ,ale vrací součet všech prvků v poli nebo jejich obsahů?

 
Odpovědět
19. června 12:39
Avatar
Alesh
Překladatel
Avatar
Odpovídá na Vojta Opravil
Alesh:19. června 13:58

Počet, ne součet!!!

 
Odpovědět
19. června 13:58
Avatar
Odpovídá na Alesh
Vojta Opravil:19. června 14:55

Takže jestli to chápu dobře tak pole,které obsahuje 3 indexy, tak size vrátí hodnotu 3 ?

 
Odpovědět
19. června 14:55
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Alesh
Překladatel
Avatar
Odpovídá na Vojta Opravil
Alesh:19. června 15:06

Jasný. Prostě v té kolekci je nějaký počet prvků, tak pokud potřebuješ informaci, kolik jich je, tak použiješ vlastnost size. Nevím, co je na tom tak složitého pochopit. Nejlepší je si to vyzkoušet přímo v programu. Prostě si udělej kolekci, něco do ní nastrkej a pak si nech vypsat size. ;-)

 
Odpovědět
19. června 15:06
Avatar
Odpovídá na Alesh
Vojta Opravil:19. června 16:45
fun main(args: Array<String>) {

    println("Zadej počet čísel: ")
    val pocet = readLine()!!.toInt()
    var cisla = arrayOf<Int>()
    for (i in 0..pocet - 1) {
        print("Zadej ${i + 1}. číslo: ")
        cisla += readLine()!!.toInt()
    }


    val cisla2 = cisla.sorted()

    val median = cisla2[cisla2.size / 2]
    for (cislo in cisla) {
        println("$cislo se od mediánu odchyluje o ${cislo - median}")
    }

}

Už tomu rozumím ,ale v "val median = cisla2[cisla2.size / 2]" mám třeba 4 čísla jejichž hodnoty budou 8,5,2,0, tak bych předpokládal že median se bude rovnat 4 / 2 = 2 a ne 5

 
Odpovědět
19. června 16:45
Avatar
Alesh
Překladatel
Avatar
Odpovídá na Vojta Opravil
Alesh:20. června 1:18

Proč?

 
Odpovědět
20. června 1:18
Avatar
Vojta Opravil:26. června 13:19
fun main(args: Array<String>) {

    var pole = arrayOf<Int>()
    pole += 34
    for(i in pole)
    print(pole)

}

Co je na tom špatně ?? Vypíšeto [Ljava.lang.In­teger;@4dc63996

 
Odpovědět
26. června 13:19
Avatar
Odpovídá na Vojta Opravil
Vojta Opravil:26. června 14:02

Už jsem našel chybu

 
Odpovědět
26. června 14:02
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 18. Zobrazit vše