In der Schleife

Arrays und Listen in Kotlin

 Zur Massenverarbeitung von mehreren Datensätzen bieten sich in Java in der Regel vier verschiedenen Kontrukte an – Array, List, Set und Map. (Ja, den Vector lassen wir hier geflissentlich außen vor … kennt den überhaupt noch jemand?)

String[] array = {"a", "b", … };
List<String> list = Arrays.asList("a", "b", … );
Set<String> set = Set.of("a", "b", … );
Map<String, String> map = Map.of("keyA", "a", "keyB", "b", … );

Das Adressieren der Elemente geschieht dann jeweils über einen Index oder Schlüssel:

array[index] = string;        string = array[index];
list.add(]index,] string);    string = list.get(index);
set.add(string);              string = set.get(index);
map.put(key, string);         string = map.get(key);

Kotlin bietet die gleichen Typen an, die Konstruktion sieht dabei so aus:

val array = arrayOf("a", "b", …) 
val list = listOf("a", "b", …)
val set = setOf("a", "b", …)
val map = mapOf("keyA" to "a", "keyB" to "b", …)

Bis auf Array sind die so erzeugten Kollektionen alle unveränderlich (Immutable). Sollen zu einem späteren Zeitpunkt Elemente hinzugefügt oder geändert werden, muss bei der Erzeugung mutableListOf(), mutableSetOf() bzw. mutableMapOf() verwendet werden. Dann sieht die Adressierung so aus:

                           array[index] = string;   string = array[index]
list.add(index, string);   list[index] = string;    string = list[index]        
set.add(string);
map.put(key, string);      map[key] = string;       string = map[key]

Kotlin erlaubt sowohl die Schreibweise mit get, set, add und put-Methoden als auch mit Indizes für alle seine Kollektionen. Um über diese Kollektionen zu itererieren, reicht dann ein for Statement aus. Während Java seit Version 5 für die Iterablen Typen ein eigenes „foreach“-Konstrukt verwendet,

for (String element : set) { … }       // Iterable Typen (Arrays und Collections)
for (int i = 0; i < max; i++) { … }    // klassisch
for (int i = 100; i > 0; i-=10) { … }

sind die Schleifen bei Kotlin einheitlich gestaltet. Wertebereiche werden hier ebenfalls wie Listen verarbeitet.

for (element in set) { … }
for (i in 0..max) { … }
for (i in 100 downTo 0 step 10) { … }

Oder man ruft .foreach { … } direkt auf dem Collection-Objekt auf. Das while/do while Konstrukt ist ebenfalls identisch vorhanden

Wenn, dann, sonst …

Zum Abschluss sollen hier noch ein paar Beispiele für die Ablaufkontrolle gegeben werden. Das klassische if kann in Kotlin sowohl als Codeblock

if (bedingung) machWas() else machWasAnderes()

als auch als Statement verstanden werden.

Object auswahl = if (bedingung) dasEine else dasAndere

Das ähnelt dem ternären Operator in Java:

Object auswahl = bedingung ? dasEine : dasAndere  // Der Fall, wo Java mal kürzer als Kotlin ist …

Beides geht hier aber auch zusammen, wenn das zurück zu gebende Objekt an letzter Stelle steht:

Object auswahl = if (bedingung) { 
    machWas()
    dasEine
} else {
    machWasAnderes()
    dasAndere
}

Für eine Mehrfach-Verzweigung gibt es das Schlüsselwort when, welches ähnlich dem Java-switch/case funktioniert. Anders als jenes erlaubt es aber auch dynamische Vergleiche, welche in der festgelegten Reihenfolge abgearbeitet werden:

when (text) {
     "a", "e", "i", "o", "u" -> { … }
     in "x".."z" -> { … }
     in set -> { … }
     is String -> { … }  // Java: instanceof
     else -> { … }
}

when kann daher auch ein komplettes if { … } else if { … } … Konstrukt ersetzen:

Object auswahl = when {
     prefix.startsWith("pre") -> { … }
     suffix.endsWith("fix") -> { … }
     else -> { … }
}