Inhalt dieser Seite
1. Einführendes Beispiel
Eine Java-Methode soll die kleinere von zwei int-Zahlen zurückliefern. Hier eine einfache Lösung:
Programm 1
public int mini(int a, int b)
{
if (a < b)
return a;
else
return b;
}
Wenn der erste Parameter a kleiner ist als der zweite Parameter b, wird a zurückgegeben. Andernfalls wird b zurückgegeben. Das funktioniert auch dann, wenn beide Zahlen gleich groß sind.
Nun wollen wir die Methode so erweitern, dass sie das Minimum von drei Zahlen zurückliefert.
Programm 2
public int mini(int a, int b, int c)
{
if ((a < b) && (a < c))
return a;
else
if (b < c)
return b;
else
return c;
}
Zunächst wird geprüft, ob a kleiner als b und gleichzeitig kleiner als c ist. In diesem Fall ist a das Minimum und wird zurückgegeben.
Wenn das nicht der Fall ist, muss entweder b oder c das Minimum sein. Deshalb werden diese beiden Zahlen miteinander verglichen und die kleinere Zahl wird zurückgegeben.
Für Experten
Wir wollen nun die kleinste von vier Zahlen finden. Dazu benutzen wir mehrfach die Methode mini(a,b), die das Minimum von zwei Zahlen liefert:
public int betterMini(int a, int b, int c, int d)
{
return mini(mini(a,b), mini(c,d));
}
Zuerst wird mit mini(a,b) die kleinere der Zahlen a und b bestimmt. Gleichzeitig liefert mini(c,d) die kleinere der Zahlen c und d.
Anschließend werden diese beiden Ergebnisse noch einmal miteinander verglichen. Auf diese Weise erhalten wir das Minimum aller vier Zahlen.
Hier noch einmal das Ganze in Farbe:
return mini ( mini(a,b), mini(c,d) );
Bei vier Zahlen ist diese Lösung noch recht übersichtlich. Bei 10, 20 oder sogar 100 Zahlen würde ein solcher Quelltext jedoch schnell sehr lang und unübersichtlich werden.
Für solche Aufgaben gibt es in der Informatik Arrays. In einem Array kann man viele Werte desselben Datentyps gemeinsam speichern und mit Schleifen bearbeiten. Im nächsten Abschnitt lernen Sie, wie das funktioniert.
2. Der Sprung ins kalte Wasser!↑
Der Sprung ins kalte Wasser
Quelle: Pixabay.com, Autor: chengtzf, Lizenz: Pixabay-Lizenz.
Wir wollen nun das Minimum von 100 Zahlen ermitteln – und zwar mit einem vergleichsweise kurzen Quelltext. Dazu verwenden wir ein sogenanntes Array.
Bevor wir uns die einzelnen Anweisungen genauer ansehen, betrachten wir zunächst das komplette Programm:
import java.util.Random;
public class Folge_7_2
{
int[] hundertZahlen;
public Folge_7_2()
{
hundertZahlen = new int[100];
}
public void erzeugeArray()
{
Random wuerfel = new Random();
for (int i = 0; i < hundertZahlen.length; i++)
hundertZahlen[i] = wuerfel.nextInt(1000) + 1;
}
public int mini()
{
int min = hundertZahlen[0];
for (int i = 1; i < hundertZahlen.length; i++)
if (hundertZahlen[i] < min)
min = hundertZahlen[i];
return min;
}
}
Kopieren Sie den Quelltext über die Zwischenablage in ein neues BlueJ-Projekt und probieren Sie das Programm aus.
Das erzeugte Objekt wird angeklickt
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain
Dieses Bild zeigt, was passiert, wenn man ein erzeugtes Objekt folge_7_2 der Klasse Folge_7_2 in BlueJ anklickt. Im Objektinspektor sehen wir nur eine Instanzvariable mit dem Namen hundertZahlen.
hundertZahlen enthält jedoch nicht selbst die 100 Zahlen. Die Variable enthält eine Referenz auf das eigentliche Array. Über diese Referenz kann Java auf die Elemente des Arrays zugreifen.
Gibt man die Variable mit
System.out.println(hundertZahlen);
aus, erhält man beispielsweise eine Zeichenfolge wie [I@78c75e93. Diese Zeichenfolge ist weder der Inhalt des Arrays noch einfach seine Speicheradresse. Für uns ist diese Ausgabe daher zunächst nicht besonders hilfreich.
Wenn wir die einzelnen Elemente des Arrays in BlueJ betrachten wollen, können wir im Objektinspektor auf den gebogenen Pfeil neben hundertZahlen klicken:
Der gebogene Pfeil im Objektinspektor wird angeklickt
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain
Direkt nach dem Erzeugen des Objekts haben alle 100 Elemente des Arrays den Wert 0. Java setzt die Elemente eines neu erzeugten int-Arrays automatisch auf den Anfangswert 0.
Erst wenn die Methode erzeugeArray() aufgerufen wird, werden diese Nullen durch Zufallszahlen ersetzt.
Nachdem wir gesehen haben, dass das Programm funktioniert, untersuchen wir nun Schritt für Schritt, wie es aufgebaut ist.
3. Gründliche Analyse des Programms↑
3.1 Erzeugen eines Arrays aus 100 int-Zahlen
Betrachten wir zunächst den Anfang des Programms. Auf die erste Zeile mit der import-Anweisung kommen wir später zurück.
Die Zeilen 3 bis 10 des Programms
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain
3.1.1 Deklaration des Arrays
Mit der Anweisung
int[] hundertZahlen;
wird eine Variable mit dem Namen hundertZahlen deklariert. Die Schreibweise int[] zeigt, dass diese Variable später auf ein Array aus int-Werten verweisen soll.
Veranschaulichung der Deklaration des Arrays
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain
Bei dieser Deklaration wird noch kein Array erzeugt. Deshalb ist auch noch nicht festgelegt, wie viele Elemente das Array später besitzen soll. Festgelegt werden zunächst nur der Datentyp int[] und der Bezeichner hundertZahlen.
3.1.2 Initialisierung des Arrays
Im Konstruktor wird das eigentliche Array erzeugt:
hundertZahlen = new int[100];
Das Schlüsselwort new sorgt dafür, dass ein neues Array erzeugt wird. Die Zahl 100 legt fest, dass dieses Array genau 100 Elemente vom Typ int besitzt.
Die bereits deklarierte Referenzvariable hundertZahlen verweist anschließend auf dieses neu erzeugte Array.
Referenzvariablen (für Experten)
Wenn Sie mit
System.out.println(hundertZahlen);
die Variable hundertZahlen in der Konsole ausgeben, erhalten Sie eine zunächst kryptisch wirkende Zeichenfolge, zum Beispiel:
[I@2f92e0f4
Diese Ausgabe ist nicht der Inhalt des Arrays und auch nicht einfach seine Speicheradresse.
Die Variable hundertZahlen enthält eine Referenz auf das Array. Man sagt daher: Die Variable hundertZahlen referenziert das Array oder verweist auf das Array.
Über diese Referenz können wir auf die einzelnen Elemente des Arrays zugreifen.
Für Super-Experten:
Gelegentlich liest man Formulierungen wie "Die Variable hundertZahlen zeigt auf das Array". Diese Vorstellung ist anschaulich. In Java spricht man fachlich aber von einer Referenz und nicht von einem Zeiger oder Pointer.
Programmiersprachen wie C und C++ kennen Zeiger, mit denen Speicheradressen direkter verarbeitet werden können. Dort gibt es auch sogenannte Zeigerarithmetik. Java erlaubt eine solche Zeigerarithmetik mit Referenzen nicht. Eine Anweisung wie
hundertZahlen++;
ist daher nicht erlaubt. Java verwaltet den Speicherzugriff weitgehend selbst. Dadurch muss man beim normalen Programmieren nicht direkt mit Speicheradressen arbeiten.
3.1.3 Deklaration und Initialisierung in einer Anweisung
Man kann Deklaration und Initialisierung auch in einer einzigen Anweisung durchführen:
int[] hundertZahlen = new int[100];
Das ist in Java vollkommen korrekt und wird auch häufig verwendet. Wenn das Array jedoch eine Instanzvariable einer Klasse ist, kann es sinnvoll sein, seine Größe erst im Konstruktor festzulegen.
Das folgende Beispiel zeigt einen Vorteil dieser Vorgehensweise:
public Beispiel(int groesse)
{
vieleZahlen = new int[groesse];
}
Die gewünschte Größe des Arrays wird dem Konstruktor als Parameter groesse übergeben. Dadurch kann beim Erzeugen eines neuen Objekts entschieden werden, wie viele Elemente das Array besitzen soll.
3.2 Füllen des Arrays mit Zufallszahlen
3.2.1 Einen Zufallsgenerator erzeugen
Wenn wir Zufallszahlen benötigen, können wir die Klasse Random verwenden. Dazu wird sie am Anfang des Programms eingebunden:
import java.util.Random;
Die Klasse Random stellt Methoden zur Erzeugung von Zufallszahlen zur Verfügung. Zunächst erzeugen wir ein Objekt dieser Klasse:
Random wuerfel = new Random();
Das Objekt der Klasse Random haben wir hier wuerfel genannt.
3.2.2 Zufallszahlen erzeugen
Eine einzelne Zufallszahl vom Typ int können wir beispielsweise so erzeugen:
x = wuerfel.nextInt(1000);
Die Variable x muss vorher als int-Variable deklariert worden sein.
wuerfel.nextInt(1000) liefert eine zufällige ganze Zahl von 0 bis 999. Wollen wir stattdessen eine Zahl von 1 bis 1000 erzeugen, schreiben wir:
wuerfel.nextInt(1000) + 1
3.2.3 Das Array mit Zufallszahlen füllen
Wir wollen nicht nur eine Zufallszahl erzeugen, sondern alle 100 Elemente des Arrays mit Zufallszahlen füllen. Man könnte theoretisch schreiben:
hundertZahlen[0] = wuerfel.nextInt(1000) + 1; hundertZahlen[1] = wuerfel.nextInt(1000) + 1; hundertZahlen[2] = wuerfel.nextInt(1000) + 1; hundertZahlen[3] = wuerfel.nextInt(1000) + 1; hundertZahlen[4] = wuerfel.nextInt(1000) + 1; ... hundertZahlen[99] = wuerfel.nextInt(1000) + 1;
Das wäre jedoch sehr umständlich. Mit einer for-Schleife geht es viel einfacher:
for (int i = 0; i < hundertZahlen.length; i++) hundertZahlen[i] = wuerfel.nextInt(1000) + 1;
Die Schleife wird 100-mal durchlaufen. Bei jedem Durchlauf wird einem Element des Arrays eine Zufallszahl von 1 bis 1000 zugewiesen.
Auf ein Arrayelement greifen wir über seinen sogenannten Index zu. Das erste Element eines Arrays besitzt immer den Index 0.
Bei einem Array mit 100 Elementen besitzt das letzte Element deshalb den Index 99 und nicht den Index 100.
Methode erzeugeArray()
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain
Denk-Aufgabe für zwischendurch
Was würde passieren, wenn man folgenden Quelltext ausführen würde?
public void erzeugeArray()
{
Random wuefel = new Random();
for (int i = 1; i <= 100; i++)
hundertZahlen[i] = wuefel.nextInt(1000) + 1;
}
Dieser Code würde einen Laufzeitfehler verursachen. Genauer gesagt wird eine Exception mit dem Namen ArrayIndexOutOfBoundsException ausgelöst.
Beim letzten Schleifendurchlauf besitzt die Laufvariable i den Wert 100. Ein Arrayelement mit dem Index 100 existiert aber nicht. Bei einem Array mit 100 Elementen reichen die erlaubten Indizes nur von 0 bis 99.
Außerdem wird das Element mit dem Index 0 in dieser fehlerhaften Schleife übersprungen.
Wie kann man einen solchen ArrayIndexOutOfBounds-Fehler vermeiden?
Jedes Array besitzt die Eigenschaft length. Sie gibt an, wie viele Elemente das Array besitzt. Deshalb kann man die Schleife so formulieren:
for (int i = 0; i < hundertZahlen.length; i++)
Diese Schreibweise hat einen weiteren Vorteil: Auch wenn die Größe des Arrays später geändert wird, funktioniert die Schleife weiterhin.
3.3 Suchen der kleinsten Zahl im Array
Das Ziel dieses Abschnitts ist eine Methode
public int mini()
die das Array hundertZahlen untersucht und die kleinste Zahl als int-Wert zurückliefert.
3.3.1 Vorbereitung
Zunächst nehmen wir an, dass das erste Element des Arrays die kleinste Zahl enthält:
int min = hundertZahlen[0];
min ist eine lokale Variable. Sie wird innerhalb der Methode deklariert und kann auch nur innerhalb dieser Methode verwendet werden.
3.3.2 Suchen nach dem Minimum
Nun untersuchen wir mit einer for-Schleife alle weiteren Elemente des Arrays:
for (int i = 1; i < hundertZahlen.length; i++) if (hundertZahlen[i] < min) min = hundertZahlen[i];
Ist das gerade untersuchte Arrayelement kleiner als der bisherige Wert von min, wird dieser kleinere Wert in min gespeichert.
Nachdem alle Elemente untersucht wurden, enthält min die kleinste Zahl des Arrays.
3.3.3 Rückgabe des Minimums
Nach der Schleife wird der Wert von min mit return zurückgegeben:
return min;
3.3.4 Der komplette Quelltext
Die Methode mini()
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain
Theorieteil:
4. Was ist überhaupt ein Array?↑
Ein Array speichert eine feste Anzahl von Elementen desselben Datentyps. Die einzelnen Elemente sind nummeriert und können über ihren Index angesprochen werden.
Unser Array aus dem vorherigen Programm besitzt 100 Elemente vom Typ int. Genauso könnte man beispielsweise ein Array mit 200 double-Werten oder 134 String-Referenzen erzeugen.
Der Datentyp der Arrayelemente muss also kein primitiver Datentyp wie int, double oder char sein. Ein Array kann auch Referenzen auf Objekte einer Klasse speichern.
Objekt-Arrays – ein Vorgeschmack
In einem Adventure-Game könnte es beispielsweise eine Klasse Gegenstand geben. Ein Gegenstand besitzt vielleicht Eigenschaften wie Name, Angriffswert, Verteidigungswert, Goldwert oder Zustand.
Benötigt man nur drei Gegenstände, kann man drei Variablen vom Typ Gegenstand deklarieren:
Gegenstand schwert, schild, helm;
Wenn diese Variablen bereits auf entsprechende Gegenstands-Objekte verweisen, könnte man ihren Gesamtwert beispielsweise so berechnen:
int gesamtwert = schwert.getWert() + schild.getWert() + helm.getWert();
In einem größeren Spiel gibt es jedoch oft sehr viele Gegenstände. Ein Held besitzt vielleicht ein Inventar mit Platz für 20 Gegenstände.
Ein solches Array kann folgendermaßen erzeugt werden:
Gegenstand[] inventar = new Gegenstand[20];
Wichtig: Damit werden zunächst nur 20 Plätze für Referenzen auf Gegenstands-Objekte erzeugt. Die Gegenstands-Objekte selbst entstehen dadurch noch nicht. Die einzelnen Elemente des Arrays enthalten zunächst den Wert null.
Ein Gegenstand könnte beispielsweise so in das Inventar eingefügt werden:
inventar[0] = new Gegenstand("Schwert", 50, 5, 100);
Wenn einige Plätze des Inventars noch leer sein können, kann der Gesamtwert folgendermaßen berechnet werden:
int gesamtwert = 0; for (int i = 0; i < inventar.length; i++) if (inventar[i] != null) gesamtwert += inventar[i].getWert();
Die Abfrage inventar[i] != null verhindert, dass auf einen noch leeren Platz des Arrays zugegriffen wird. Voraussetzung ist natürlich außerdem, dass die Klasse Gegenstand eine Methode getWert() besitzt.
4.1 Die Deklaration eines Arrays
4.1.1 Wie deklariert man ein Array?
Vergleichen wir die Deklaration einer einzelnen int-Variablen mit der Deklaration einer Variablen für ein int-Array:
int eineZahl; int[] achtZahlen;
Die Variable heißt zwar achtZahlen, die Größe des Arrays ist zu diesem Zeitpunkt aber noch nicht festgelegt. Das geschieht erst beim Erzeugen des Arrays.
Auf die gleiche Weise kann man Variablen für Arrays anderer Datentypen deklarieren:
double[] zwanzigZahlen; String[] textseite;
Auch Arrays mit Referenzen auf Objekte bestimmter Klassen sind möglich:
Gegenstand[] inventar; Person[] gehaltsliste; LKW[] fuhrpark;
4.1.2 Was passiert bei der Deklaration?
Bei der Deklaration wird zunächst eine Referenzvariable angelegt. Das eigentliche Array existiert zu diesem Zeitpunkt noch nicht.
int[] achtZahlen;
Ist achtZahlen eine Instanzvariable einer Klasse, besitzt sie zunächst automatisch den Wert null. Das bedeutet: Sie verweist noch auf kein Array.
Hinweis: Lokale Variablen innerhalb einer Methode erhalten in Java nicht automatisch den Wert null. Sie müssen vor ihrer ersten Verwendung einen Wert erhalten.
4.2 Die Initialisierung eines Arrays
Mit dem Schlüsselwort new wird das eigentliche Array erzeugt. Dabei wird auch festgelegt, wie viele Elemente es besitzen soll:
achtZahlen = new int[8];
Hier wird ein Array mit acht Elementen vom Typ int erzeugt. Die Referenzvariable achtZahlen verweist anschließend auf dieses Array.
4.3 Wertzuweisung an Arrayelemente
4.3.1 Ein Beispiel
achtZahlen[0] = 1; achtZahlen[1] = 4; achtZahlen[2] = 9;
Der Zugriff auf ein Arrayelement erfolgt über seinen Index. Das erste Element besitzt immer den Index 0.
4.3.2 Weitere Beispiele
zahl[0] = 13;
Dem ersten Element des Arrays zahl wird der Wert 13 zugewiesen.
temperatur[12] = 27.3;
Dem dreizehnten Element des Arrays temperatur wird der Wert 27.3 zugewiesen. Offensichtlich handelt es sich hier um ein double-Array.
inventar[2] = new Gegenstand("Hammer", 0, 45, 2);
Zuerst wird ein neues Objekt der Klasse Gegenstand erzeugt. Anschließend wird eine Referenz auf dieses Objekt im dritten Element des Arrays inventar gespeichert.
4.4 Zugriff auf Arrayelemente
4.4.1 Beispiele
System.out.println(zahl[3]);
Der Wert des vierten Arrayelements wird auf der Konsole ausgegeben.
int ergebnis = zahl[2];
Der Wert des dritten Arrayelements wird ausgelesen und in der Variablen ergebnis gespeichert.
int summe = zahl[0] + zahl[1] + zahl[2];
Die Werte der ersten drei Arrayelemente werden addiert.
if (zahl[1] < 0) zahl[1] = 0;
Auch in einer if-Anweisung kann auf Arrayelemente zugegriffen werden. Ist das zweite Element negativ, wird sein Wert hier auf 0 gesetzt.
inventar[4].ausgeben();
Bei einem Objekt-Array kann über ein Arrayelement auf das zugehörige Objekt zugegriffen werden. Hier wird die Methode ausgeben() des Objekts aufgerufen, auf das inventar[4] verweist.
Voraussetzung ist, dass inventar[4] tatsächlich auf ein Objekt verweist und nicht den Wert null besitzt.
4.4.2 Weitere Beispiele
int y = zahl[0];
Der Wert des ersten Arrayelements wird ausgelesen und der int-Variablen y zugewiesen.
System.out.println(temperatur[12]);
Der Wert des 13. Arrayelements mit dem Index 12 wird ausgelesen und auf der Konsole ausgegeben.
if (zahlenliste[4] >= 20) bedingung = true; else bedingung = false;
Das fünfte Arrayelement wird mit der Zahl 20 verglichen. Ist sein Wert größer oder gleich 20, erhält die boolean-Variable bedingung den Wert true. Andernfalls erhält sie den Wert false.
bedingung = (zahlenliste[4] >= 20);
Diese Anweisung bewirkt dasselbe wie die vorherige if-else-Anweisung. Der Vergleich zahlenliste[4] >= 20 liefert direkt den Wert true oder false, der anschließend in bedingung gespeichert wird.
inventar[3].beschaedigen(20);
Das vierte Element des Arrays inventar verweist auf ein Objekt der Klasse Gegenstand. Für dieses Objekt wird die Methode beschaedigen() mit dem Parameter 20 aufgerufen.
Seitenanfang -
Weiter mit "Einfache Arrays, Teil 2"...