CodeGym /Kurse /JAVA 25 SELF /Grundlegende Operationen mit eindimensionalen Arrays

Grundlegende Operationen mit eindimensionalen Arrays

JAVA 25 SELF
Level 7, Lektion 2
Verfügbar

1. Array des Typs String

Kurz noch etwas zum Array des Typs String.

Wie schon gesagt, kann ein Array jeden Typ haben. Das heißt, man kann ein Array des Typs String erstellen. So könnte der Code aussehen, wenn wir ein Programm schreiben müssten, das „10 Zeilen von der Tastatur einliest und sie in umgekehrter Reihenfolge auf dem Bildschirm ausgibt“.

String[] array = new String[10];	// Erstellen eines Array-Objekts mit 10 Elementen
for (int i = 0; i < 10; i++)		// Schleife von 0 bis 9
{
   array[i] = console.nextLine();	// Eine Zeile von der Tastatur lesen und in einer Array-Zelle speichern
}
for (int i = 9; i >= 0; i--)		// Schleife von 9 bis 0
{
    System.out.println(array[i]);	// Das aktuelle Array-Element auf dem Bildschirm ausgeben
}

Der Code hat sich praktisch nicht geändert! Lediglich beim Erzeugen des Arrays haben wir den Typ int durch String ersetzt. Ansonsten bleibt alles genau gleich!

Einführung in null

Hier ein Rätsel – was steckt in den Zellen jedes dieser Arrays unmittelbar nach der Erstellung?

int[] numbers = new int[10];
String[] strings = new String[10];
User[] users = new User[10];

Überlegt man, enthalten die Zellen von numbers wahrscheinlich 0. Richtig.

Nach derselben Logik müssten die Zellen von strings mit leeren Strings – "" – gefüllt sein. Nehmen wir es an.

Womit sind dann die Zellen des Arrays users gefüllt? Mit leeren User-Objekten?

Hier liegt der Haken: Für nicht jeden Datentyp gibt es einen „Standardwert“. Deshalb haben die Java-Entwickler die spezielle Konstante null eingeführt. null ist eine leere Referenz. Wenn eine Variable für einen Objekttyp erstellt wird, ist ihr Startwert null: eine Referenz auf nichts, das Ausbleiben einer Referenz.

String name; 	// name enthält null
name = "Alex";  // name enthält eine Referenz auf das Objekt/den String "Alex"
name = null; 	// name enthält null

Arbeiten mit null

Methoden eines Objekts können nicht aufgerufen werden, wenn die Referenz darauf null ist – es gibt ja kein Objekt! Bei solchem Code endet das Programm mit einem Fehler:

String name; 	// name enthält null
String upperName = name.toUpperCase(); // Führt zu NullPointerException: name == null

Bezüglich unseres „Rätsels“ lautet die Antwort so:

int[] numbers = new int[10];		// {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
String[] strings = new String[10];  // {null, null, null, null, null, null, null, null, null, null}
User[] users = new User[10];		// {null, null, null, null, null, null, null, null, null, null}

Nur die primitiven Typen haben einen „Standardwert“. Alle anderen Typen haben standardmäßig den Wert null. Der Startwert von String ist kein leerer String. So ist das Leben.

2. Array des Typs String im Speicher

Abbildung 1. Wie ein Objekt String im Speicher liegt:

Array des Typs String im Speicher

Beachten Sie, dass der Text der Zeichenkette nicht direkt in der Variablen gespeichert wird: Dafür wird ein separater Speicherblock reserviert. In einer Variablen vom Typ String wird die Adresse (Referenz) auf das Objekt mit dem Text gespeichert.

Abbildung 2. Wie ein Array ganzer Zahlen im Speicher liegt:

int-Array im Speicher

Diese Abbildung haben Sie ebenfalls gesehen.

Abbildung 3. Wie ein Array von Strings im Speicher liegt:

Wie ein String-Array im Speicher angeordnet ist

Links sehen wir eine Array-Variable des Typs String[] (sie speichert die Adresse des Array-Objekts).

In der Mitte – das Array-Objekt vom Typ String.

Und rechts – die String-Objekte, die irgendeinen Text enthalten.

In den Zellen des Array-Objekts vom Typ String werden nicht die Strings (Texte) selbst gespeichert, sondern deren Adressen (Referenzen). Genauso wie in Variablen vom Typ String Adressen der Strings (des Textes) gespeichert werden.

3. Schnelle Array-Initialisierung in Java

Arrays sind sehr nützlich, deshalb haben die Java-Entwickler die Arbeit damit so bequem wie möglich gemacht. Das Erste, was sie getan haben – sie haben die Initialisierung von Arrays vereinfacht, also das Eintragen von Startwerten.

Sehr oft braucht ein Programm neben Daten, die es irgendwoher einliest, auch eigene interne Daten. Zum Beispiel möchten wir die Längen aller Monate in einem Array speichern. So könnte der Code aussehen:

int[] months = new int[12];
months[0] = 31; // Januar
months[1] = 28; // Februar
months[2] = 31; // März
months[3] = 30; // April
months[4] = 31; // Mai
months[5] = 30; // Juni
months[6] = 31; // Juli
months[7] = 31; // August
months[8] = 30; // September
months[9] = 31; // Oktober
months[10] = 30; // November
months[11] = 31; // Dezember

Aber es gibt eine kürzere Schreibweise – danke an die Java-Entwickler:

// Längen der Monate des Jahres
int[] months = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Man kann einfach alle Werte des Arrays durch Komma getrennt aufzählen!

Der Compiler kann den Typ des Containers (Array-Objekts) anhand des Typs der Array-Variablen bestimmen. Und um die Länge des Arrays zu bestimmen, zählt er schlicht die Anzahl der Elemente in den geschweiften Klammern.

Daher kann man diesen Code noch kürzer schreiben:

// Längen der Monate des Jahres
int[] months = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Ist das nicht schön? 🙂 Diese Schreibweise nennt man „schnelle Array-Initialisierung“. Sie funktioniert übrigens nicht nur für den Typ int ...

// Monatsnamen
String[] months = { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" };

4. Schleife for-each

Das Durchlaufen aller Elemente eines Arrays ist so häufig, dass es dafür eine spezielle Schleife gibt – for-each. Sie wird so geschrieben:

for (int score : scores)
{
    System.out.println("Punkte: " + score);
}
Durchlaufen der Array-Elemente mit for-each

Hier iteriert die Schleife selbst über die Elemente – kein manueller Index. Allerdings kann man die Elemente nicht direkt ändern (in der Schleifenvariablen steht nur eine Kopie des Werts), dafür ist es sehr bequem, einfach „über das Array zu laufen“.

Der Compiler verwandelt den for-each-Code in den untenstehenden Code:

for (int i = 0; i < scores.length; i++)
{
    int score = scores[i];
    System.out.println("Punkte: " + score);
}
Wie for-each „unter der Haube“ funktioniert

Also keine Magie. Jetzt versteht man, warum Sie die Array-Elemente nicht über die Variable score ändern können.

Schreiben wir noch ein Beispiel: Wir finden die Summe aller Punkte.

int sum = 0;
for (int score : scores)
{
    sum += score;
}
System.out.println("Summe aller Punkte: " + sum);
Summe der Array-Werte per for-each berechnen

Wann welche Schleife verwenden?

  • Wenn ein Index benötigt wird oder Elemente geändert werden sollen – die Schleife for.
  • Wenn man nur über die Werte iteriert – for-each ist schneller und sauberer.

5. Ändern von Array-Elementen

Was, wenn wir jede Note um 1 Punkt erhöhen möchten (z. B. für gutes Verhalten)? Dann brauchen wir die klassische for-Schleife mit Index, denn nur so können wir die Werte im Array ändern.

Beispiel: jedes Element um 1 erhöhen

for (int i = 0; i < grades.length; i++) {
    grades[i] = grades[i] + 1;
}

Nach der Ausführung dieses Codes enthält das Array grades neue Werte.

Warum geht das nicht mit for-each?

for (int grade : grades) {
    grade = grade + 1; // Funktioniert nicht!
}

Dieser Code ändert das Array nicht, weil grade eine Kopie des Werts aus dem Array ist und keine Referenz auf das Element selbst.

6. Berechnungen auf Basis eines Arrays

Arrays werden oft für Berechnungen verwendet: Summe, Durchschnitt, Maximum, Minimum und so weiter.

Beispiel: Summe aller Array-Elemente

int sum = 0;
for (int i = 0; i < grades.length; i++) {
    sum += grades[i]; // dasselbe wie sum = sum + grades[i];
}
System.out.println("Summe der Noten: " + sum);

Beispiel: das Maximum finden

int max = grades[0]; // beginnen wir mit dem ersten Element
for (int i = 1; i < grades.length; i++) {
    if (grades[i] > max) {
        max = grades[i];
    }
}
System.out.println("Höchste Note: " + max);

Beispiel: das Minimum finden

int min = grades[0]; // beginnen wir mit dem ersten Element
for (int i = 1; i < grades.length; i++) {
    if (grades[i] < min) {
        min = grades[i];
    }
}
System.out.println("Niedrigste Note: " + min);

Beispiel: arithmetisches Mittel berechnen

int sum = 0;
for (int i = 0; i < grades.length; i++) {
    sum += grades[i];
}
double average = (double) sum / grades.length; // unbedingt zu double casten!
System.out.println("Durchschnittsnote: " + average);

Beachten Sie: Um keine Ganz-, sondern eine Gleitkommazahl zu erhalten, muss die Summe vor der Division explizit in den Typ double umgewandelt werden.

7. Praktische Aufgaben

Ein Array von der Tastatur einlesen

Oft muss man ein Array mit Werten füllen, die der Benutzer eingibt. Dafür verwenden wir die Klasse Scanner und eine Schleife.

Scanner console = new Scanner(System.in);

int n = 5; // Array-Größe
int[] numbers = new int[n];

System.out.println("Geben Sie " + n + " Zahlen ein:");
for (int i = 0; i < n; i++) {
    numbers[i] = console.nextInt();
}

System.out.println("Sie haben eingegeben:");
for (int i = 0; i < n; i++) {
    System.out.println(numbers[i]);
}

Ausgabe des Arrays in umgekehrter Reihenfolge

Manchmal muss man die Elemente eines Arrays von hinten ausgeben (z. B. um zu sehen, wer als Letzter den Raum betreten hat).

for (int i = grades.length - 1; i >= 0; i--) {
    System.out.println("Note Nr. " + (i + 1) + ": " + grades[i]);
}

8. Typische Fehler bei der Arbeit mit eindimensionalen Arrays

Fehler Nr. 1: Zugriff außerhalb der Array-Grenzen

Das häufigste Problem ist der Versuch, auf ein nicht existentes Element zuzugreifen. In Java führt das zur Ausnahme ArrayIndexOutOfBoundsException. Denken Sie daran: Der letzte zulässige Index ist arr.length - 1.

int[] arr = new int[5];
System.out.println(arr[5]); // Fehler! Indizes von 0 bis 4.

Fehler Nr. 2: Array nicht initialisiert

Die Variable wurde deklariert, aber das Array nicht erstellt:

int[] arr;
arr[0] = 5; // Fehler! Array wurde nicht erstellt.

Sie müssen das Array unbedingt mit new erzeugen:

arr = new int[10];

Fehler Nr. 3: Versuch, Array-Elemente über for-each zu ändern

In der for-each-Schleife ist die Variable eine Kopie des Werts und keine Referenz auf das Element:

for (int x : arr) {
    x = 100; // Ändert das Array nicht!
}

Um Werte zu ändern, verwenden Sie die gewöhnliche for-Schleife mit Index.

Fehler Nr. 4: Länge des Arrays falsch verwendet

Man verwechselt manchmal die Länge des Arrays mit dem letzten Index:

for (int i = 0; i <= arr.length; i++) { // Fehler! Es muss i < arr.length heißen
    // ...
}

Solcher Code führt zu einem Zugriff außerhalb der Grenzen.

Fehler Nr. 5: implizite Typumwandlung

Wenn das Array vom Typ int ist, kann man ihm nicht direkt einen Wert vom Typ double zuweisen:

int[] arr = new int[3];
arr[0] = 3.14; // Fehler! 3.14 ist ein double.
1
Aufgabe
JAVA 25 SELF, Level 7, Lektion 2
Gesperrt
Ersteinrichtung der Highscore-Tabelle 🚀
Ersteinrichtung der Highscore-Tabelle 🚀
1
Aufgabe
JAVA 25 SELF, Level 7, Lektion 2
Gesperrt
Sammlung der Lieblingsfilme in umgekehrter Reihenfolge 🎞️
Sammlung der Lieblingsfilme in umgekehrter Reihenfolge 🎞️
1
Aufgabe
JAVA 25 SELF, Level 7, Lektion 2
Gesperrt
Berechnung der Gesamtsumme der Einkäufe im Warenkorb 🛍️
Berechnung der Gesamtsumme der Einkäufe im Warenkorb 🛍️
1
Aufgabe
JAVA 25 SELF, Level 7, Lektion 2
Gesperrt
Bestimmung der maximalen Temperatur des Tages 🌡️
Bestimmung der maximalen Temperatur des Tages 🌡️
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION