Ähnlich wie in anderen Programmiersprachen bieten Arrays in Kotlin die Möglichkeit, eine geordnete Sammlung von Elementen desselben Datentyps zu speichern und zu verwalten, beispielsweise eine Liste von Zahlen, Zeichen oder Objekten. Sie ermöglichen eine strukturierte und organisierte Speicherung von Daten sowie einen effizienten Zugriff auf einzelne Elemente über einen Index. Arrays werden in vielen Anwendungsfällen eingesetzt, von einfachen Listen über Tabellen bis hin zu komplexeren mehrdimensionalen Datenstrukturen. In Kotlin sind Arrays Objekte, die den speziell entwickelten Datentyp Array haben.
Die Haupteigenschaften von Arrays in Kotlin sind:
Gleicher Datentyp von beinhalteten Elementen: Das bedeutet, dass alle Objekte innerhalb eines Arrays den gleichen Datentyp haben müssen. Zum Beispiel nur Int, String oder Double etc., beispielsweise eine Kombination aus Int und String würde zu einem Programmfehler führen.
Um den Datentyp für die Elemente innerhalb eines Arrays vorzugeben, wird bei der Deklaration eines Arrays in spitzen Klammern nach dem Array-Typ der Typ von beinhalteten Objekten angegeben. Im folgenden Beispiel wird ein Array von Int-Werten erstellt:
val arrayOfNumbers: Array<Int> // 'arrayOfNumbers' ist Variablenname. 'Array' ist Datentyp der Variable. '<Int>' bedeutet, dass das Array ausschließlich Werte des Datentyps 'Int' speichern kann.
Im nächsten Schritt wird mithilfe der integrierten Funktion arrayOf() eine Reihe von Int-Werten an Array übergeben:
val arrayOfNumbers: Array<Int> = arrayOf(1, 2, 3, 4, 5) // Es wird ein Array mit dem Namen 'arrayOfNumbers' vom Typ 'Array<Int>' deklariert und gleichzeitig mit Hilfe der Funktion 'arrayOf()' mit den Int-Werten 1, 2, 3, 4 und 5 initialisiert.
val arrayOfNumbers2: Array<Int> = arrayOf(1, 2, 3, 4, "Tom") // Der Versuch, ein Element vom Typ String hinzuzufügen, führt zu einem Fehler.
Indizierte Elemente: Die Elemente in einem Array sind indiziert, d.h. sie haben eine bestimmte Position innerhalb des Arrays, auf die über den zugeordneten Index zugegriffen werden kann. Die Indexierung von Arrays beginnt bei 0, d.h. das erste Element hat den Index 0, das zweite Element den Index 1, das dritte den Index 2 und so weiter. Der Index wird in eckigen Klammern angegeben. Schauen wir unser vorheriges Beispiel an:
fun main() {
val arrayOfNumbers: Array<Int> = arrayOf(1, 2, 3, 4, 5)
println(arrayOfNumbers[0]) // Hier wird der Wert des Elements mit Index '0' ausgegeben, also '1'.
println(arrayOfNumbers[1]) // 2
println(arrayOfNumbers[4]) // 5
arrayOfNumbers[0] = 44 // Element mit Index '0' wird geändert von '1' auf '44'
println(arrayOfNumbers[0]) // 22
}
Feste Größe: Arrays haben eine feste Größe, die bei der Erstellung festgelegt wird. Nach der Erstellung kann die Größe eines Arrays nicht mehr verändert werden. Im nachstehenden Beispiel versuchen wir ein zusätzliches Element mit Index 5 in das Array hinzufügen:
fun main() {
val arrayOfNumbers: Array<Int> = arrayOf(1, 2, 3, 4, 5)
arrayOfNumbers[5] = 66 // Anweisung, um ein Element mit Index '5' und mit dem Wert '66' dem Array 'arrayOfNumbers' hinzufügen.
// Es wird Fehler 'Index 5 out of bounds for length 5' ausgegeben, da die Größe eines Arrays nicht verändert werden darf.
println(arrayOfNumbers[5])
}
Für die Erstellung eines Arrays in Kotlin kann man auch den Konstruktor der Klasse Array nutzen, welcher zwei Parameter annimmt. Der erste Parameter gibt die Größe des Arrays an, während der zweite Parameter das Initialisierungslambda enthält. Das Initialisierungslambda ist ein Ausdruck, welcher für jedes Element des Arrays ausgeführt wird und den initialen Wert für das jeweilige Element berechnet.
fun main() {
val arrayOfNumbers: Array<Int> = Array(3, {2*5}) // Parameter '3' definiert die Arraygröße, also das Array hat 3 Elemente.
// Der Ausdruck '{2*5}' wird für jedes Element des Arrays ausgeführt.
// Somit besteht das Array aus 3 Elementen mit dem Wert '10' [10. 10. 10].
for (element in arrayOfNumbers) {
println(element) // 10, 10, 10
}
}
Das Initialisierungslambda kann auch komplexere Ausdrücke beinhalten und somit anspruchsvollere Berechnungen ausführen.
fun main() {
var i:Int = 1
val arrayOfNumbers: Array<Int> = Array(5, {i++ * 2})
for (element in arrayOfNumbers) {
println(element) // 2, 4, 6, 8, 10
}
}
Iteration über Arrays in Kotlin
In Kotlin kann man Arrays auf verschiedene Weise durchlaufen und auf deren Elemente zugreifen. Eine Möglichkeit besteht darin, eine for-Schleife zu verwenden. Beispiel:
fun main() {
val arrayOfNames: Array<String> = arrayOf("Tom", "Jerry", "Anna", "Frank", "Mandy")
for (name in arrayOfNames) {
println(name)
}
}
Eine weitere Möglichkeit besteht darin, im Rahmen einer for-Schleife den Index als Laufvariable zu verwenden, um die Elemente eines Arrays nacheinander zu durchlaufen.
fun main() {
val arrayOfNames: Array<String> = arrayOf("Tom", "Jerry", "Anna", "Frank", "Mandy")
for (i in arrayOfNames.indices) {
println("Name at index $i is ${arrayOfNames[i]}")
}
}
Eine schlanke Alternative ist die Verwendung der forEach()-Funktion, die für jedes Element im Array eine Aktion ausführt.
fun main() {
val arrayOfNumbers: Array<Int> = arrayOf(1, 2, 3, 4, 5)
arrayOfNumbers.forEach { println(it) }
}
Die Funktion forEach führt den angegebenen Lambdaausdruck (Lambdafunktion) für jedes Element des Arrays auf, wobei jedes Element als Argument an den Lambdausdruck übergeben wird. Das Wort it in der Lambda-Funktion steht für das aktuelle Element, auf das die Aktion innerhalb der Funktion angewendet wird.
Bemerkung: Das Schlüsselwort it steht in Kotlin für einen impliziten Namen des einzelnen Parameters in einer Lambda-Funktion. Wenn eine Lambda-Funktion einen einzigen Parameter hat, kann der Parametername weggelassen werden und stattdessen das implizite it verwendet werden.
Überprüfen, ob ein Element in einem Array vorhanden ist
Nehmen wir mal an, wir haben die Aufgabe ein Array auf Vorhandensein des Namens „Jerry“ zu überprüfen. Dafür haben wir zwei Optionen. Option Nummer 1 ist die Verwendung des in-Operators:
fun main() {
val arrayOfNames: Array<String> = arrayOf("Tom", "Jerry", "Anna", "Frank", "Mandy")
if ("Jerry" in arrayOfNames) {
println("The name 'Jerry' is included")
} else {
println("The name 'Jerry' is not included")
}
}
Es ist auch möglich, eine Schleife zu verwenden, um alle Elemente des Arrays nacheinander zu durchlaufen und zu überprüfen, ob jedes Element dem gesuchten Element entspricht. Beispiel:
fun main() {
val arrayOfNames: Array<String> = arrayOf("Tom", "Jerry", "Anna", "Frank", "Mandy")
for (name in arrayOfNames) {
if (name == "Jerry") {
println("The name 'Jerry' is included")
break
}
}
}
Spezielle Funktionen für Initialisierung von Arrays für primitive Datentypen
In Kotlin gibt es für jeden primitiven Datentyp einen speziellen Array-Typ. Dazu gehören BooleanArray, ByteArray, ShortArray, IntArray, LongArray, CharArray, FloatArray und DoubleArray. Diese speziellen Array-Typen ermöglichen die Erstellung von Arrays für den jeweiligen Datentyp, was die Handhabung und Verarbeitung von Daten erleichtert.
val intArray: IntArray = intArrayOf(1, 2, 3, 4, 5) // Initialisierung des Arrays namens 'intArray' mithilfe der Funktion intArrayOf() und mit festzugewiesenen Int-Werten 1, 2, 3, 4, 5
val longArray: LongArray = longArrayOf(1L, 2L, 3L)
val floatArray: FloatArray = floatArrayOf(1.0f, 2.0f, 3.0f)
val doubleArray: DoubleArray = doubleArrayOf(1.0, 2.0, 3.0)
val charArray: CharArray = charArrayOf('a', 'b', 'c')
val booleanArray: BooleanArray = booleanArrayOf(true, false, true)
Die Initialisierung dieser Arrays kann entweder durch eine explizite Zuweisung von Werten erfolgen, wie in obigen Beispielen, oder durch die Verwendung von Konstruktoren, die für die speziellen Array-Typen definiert sind.
val intArray = IntArray(7) // Int-Array mit der Länge '7' und dem Standardwert '0'
val longArray = LongArray(3) // Long-Array mit der Länge '3' und dem Standardwert '0'
val floatArray = FloatArray(2) // Float-Array mit der Länge '2' und dem Standardwert '0.0'
val doubleArray = DoubleArray(4) // Double-Array mit der Länge '4' und dem Standardwert '0.0'
val charArray = CharArray(6) // Char-Array mit der Länge '6' und dem Standardwert '\u0000'
val booleanArray = BooleanArray(3) // Boolean-Array mit der Länge '3' und dem Standardwert 'false'
val intArray = IntArray(7) { -1 } // Int-Array mit der Länge '7' und dem Standardwert '-1'
val longArray = LongArray(3) { 100L } // Long-Array mit der Länge '3' und dem Standardwert '100L'
val floatArray = FloatArray(2) { 1.0f } // Float-Array mit der Länge '2' und dem Standardwert '1.0f'
val doubleArray = DoubleArray(5) { 3.14 } // Double-Array mit der Länge '5' und dem Standardwert '3.14'
val charArray = CharArray(6) { '!' } // Char-Array mit der Länge '6' und dem Standardwert '!'
val booleanArray = BooleanArray(4) { true } // Boolean-Array mit der Länge '4' und dem Standardwert 'true'
Multidimensionale Arrays
Zuvor haben wir ausschließlich eindimensionale Arrays betrachtet, die man sich als eine Folge oder eine Zeile von Werten vorstellen kann.
// Beispiele von eindimesionalen Arrays
val arrayOfIntegers: Array<Int> = arrayOf(1, 2, 3, 4, 5)
val arrayOfNames: Array<String> = arrayOf("Tom", "Max", "Anna", "Jerry", "Jack")
In der Softwareentwicklung gibt es jedoch mehrere Anwendungsfälle, bei denen die Darstellung und Verarbeitung komplexerer, mehrdimensionaler Datenstrukturen erforderlich ist. Einige der häufigsten und bekanntesten Nutzungsszenarien für multidimensionale Datenorganisation sind: Abbildung von Tabellen und Matrizen mit Zahlen zur Durchführung von Berechnungen oder Darstellung von Pixelwerten in Bildern sowie Volumenwerten in 3D-Modellen. Zur Speicherung und Verarbeitung solcher Datenstrukturen in Kotlin werden multidimensionale Arrays verwendet.
Multidimensionale Arrays in Kotlin sind Datenstrukturen, die aus verschachtelten Arrays bestehen und Daten in mehreren Dimensionen oder Ebenen organisieren. Sie können als Arrays von Arrays betrachtet werden.
Ein zweidimensionales Array (2D-Array) ist beispielweise wie eine Tabelle, in der Daten in Zeilen und Spalten angeordnet sind.
fun main() {
// Erstellt ein 2D-Array mit 3 Zeilen und 3 Spalten mit Initialwerten '0'
val matrix = Array(3) { Array(3) { 0 } }
// Füllt das Array mit Werten
matrix[0] = arrayOf(1, 2, 3)
matrix[1] = arrayOf(4, 5, 6)
matrix[2] = arrayOf(7, 8, 9)
// Um auf die Elemente von Unterarrays in einem zweidimensionalen Array zuzugreifen,
// sind zwei Indizes erforderlich. Mit dem ersten Index wird die Zeile abgerufen und
// mit dem zweiten Index die Spalte innerhalb dieser Zeile.
val number1 = matrix[1][2] // Zeile mit Index '1', Spalte mit Index '2'
println(number1) // Ausgabe '6'
val number2 = matrix[2][0] // Zeile mit Index '1', Spalte mit Index '2'
println(number2) // Ausgabe '7'
}
Mit Hilfe von zwei ineinander geschachtelten Schleifen ist es auch möglich, zweidimensionale Arrays durchzulaufen.
fun main() {
// Erstellt ein 2D-Array mit 3 Zeilen und 3 Spalten mit Initialwerten '0'
val matrix = Array(3) { Array(3) { 0 } }
// Füllt das Array mit Werten
matrix[0] = arrayOf(1, 2, 3)
matrix[1] = arrayOf(4, 5, 6)
matrix[2] = arrayOf(7, 8, 9)
// Gibt das Array aus
for (row in matrix) {
for (value in row) {
print("$value ")
}
println()
}
}
Ein dreidimensionales Array (3D-Array) ist wie ein Stapel von Tabellen übereinander und kann durch Verschachtelung eines Arrays von 2D-Arrays erstellt werden.
fun main() {
// Erstellt ein 3D-Array mit 2 Schichten, 3 Zeilen und 3 Spalten
val array3D = Array(2) { Array(3) { Array(3) { 0 } } }
// Füllt das 3D-Array mit Werten
array3D[0] = arrayOf(
arrayOf(1, 2, 3),
arrayOf(4, 5, 6),
arrayOf(7, 8, 9)
)
array3D[1] = arrayOf(
arrayOf(10, 11, 12),
arrayOf(13, 14, 15),
arrayOf(16, 17, 18)
)
// Um auf die Elemente von Unterarrays in einem dreidimensionalen Array zuzugreifen,
// sind drei Indizes erforderlich. Mit dem ersten Index wird das Array angesprochen,
// mit dem zweiten Index die Zeile innerhalb des Array abgerufen und
// mit dem dritten Index die Spalte innerhalb dieser Zeile.
val number1 = array3D[0][2][0] // Array mit Index '0', Zeile mit Index '2', Spalte mit Index '0'
println(number1) // Ausgabe '7'
val number2 = array3D[1][1][1] // Array mit Index '1', Zeile mit Index '1', Spalte mit Index '1'
println(number2) // Ausgabe '14'
println() // Leere Zeile
// Gibt das 3D-Array aus
for (layer in array3D) {
for (row in layer) {
for (value in row) {
print("$value ")
}
println()
}
println("----")
}
}
In den obigen Beispielen wurden 2D- und 3D-Arrays erstellt und mit Werten gefüllt. Beachte, dass diese Beispiele Arrays mit fester Größe verwenden, aber man kann auch ArrayLists verwenden, um dynamische, multidimensionale Arrays zu erstellen. Dieses Thema werden wir im weiteren Verlauf des Tutorials detailliert betrachten.