Home > Informatik > Stufe EF > Folge 7 (Arrays)

7.1 Einfache Arrays, Teil 1

Arrays - Objekt-Arrays - verstehen - Held

Inhalt dieser Seite

1. Einführendes Beispiel

Eine Java-Methode soll die kleinere von zwei int-Zahlen zurückliefern. Hier eine spontane Lösungsidee:

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 (b), wird er als die "kleinste Zahl" interpretiert und zurückgeliefert. Ist der a jedoch nicht kleiner als b, wird b als "kleinste Zahl" zurückgeliefert, selbst dann, wenn b genau so groß ist wie a.

Nun wollen wir die Methode so erweitern, dass das Minimum von drei Zahlen zurückgeliefert wird.

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 mit Hilfe einer etwas komplexeren Abfrage festgestellt, ob a die kleinste der drei Zahlen ist.

Wenn das nicht der Fall ist, muss b oder c die kleinste Zahl sein. Dazu wird einfach b mit c verglichen und je nach Ergebnis b oder c als Wert zurückgegeben.

Für Experten

Wir wollen die kleinste von vier Zahlen finden. Dazu benutzen wir 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));
    }

Diese Methode betterMini(a,b,c,d) findet mit Hilfe von mini(a,b) die kleinere der beiden Zahlen a und b und mit Hilfe von mini(c,d) das Minimum von c und d. Die beiden Minima werden dann erneut der Methode mini() übergeben, so dass jetzt das Gesamt-Minimum gefunden wird.

Hier der besseren Übersichtlichkeit noch einmal das Ganze in Farbe:

return mini ( mini(a,b), mini(c,d) );

Die Experten-Lösung mag ja noch ganz gut sein, wenn man das Minimum von vier Zahlen sucht. Bei fünf oder sechs Zahlen wird der Quelltext schon etwas länger, bei sieben oder acht Zahlen noch länger und unübersichtlicher, und bei 10, 20 oder gar 100 Zahlen völlig unübersichtlich.

Aber man hat ja in der Informatik das Prinzip des Arrays entwickelt, um solche Probleme besser bewältigen zu können. Aber der Übergang von einzelnen Zahlen zu einem Array von Zahlen ist wie ein Sprung ins kalte Wasser. Man muss etwas völlig Neues lernen. Aber das ist ja andererseits der Sinn dieses Kurses, das Sie etwas Neues lernen.

2. Der Sprung ins kalte Wasser!

Der Sprung ins kalte Wasser
Quelle: Pixabay.com, Autor: chengtzf, Lizenz: Pixabay-Lizenz.

Genug mit den hilflosen Versuchen, das Minimum von 4, 5, 6 oder mehr Zahlen zu ermitteln. Wir wollen jetzt das Minimum von 100 Zahlen ermitteln - und das mit einem sehr kurzen Quelltext. Dazu benutzen wir einen Array. Bevor wir hier mit langen und langweiligen Erklärungen anfangen, schauen wir uns einfach mal ein Beispiel an. Erklärungen kommen dann später.

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<100; i++)
           hundertZahlen[i] = wuerfel.nextInt(1000)+1;
    }
    
    public int mini() 
    {
       int min = hundertZahlen[0];
       for (int i=1; i<100; i++)
          if (hundertZahlen[i] < min)
             min = hundertZahlen[i];
             
       return min;
    }
}

Das ist schon ein recht langes Programm. Kopieren Sie es sich über die Zwischenablage in ein neues BlueJ-Projekt und probieren Sie es aus. Es funktioniert einwandfrei.

Das erzeugte Objekt wird angeklickt
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain

Dieses Bild zeigt, was passiert, wenn man das erzeugte Objekt der Klasse in BlueJ anklickt. Im Objektinspektor sehen wir nur eine einzige Variable, nämlich den Array mit dem Namen hundertZahlen.

Tatsächlich ist ein Array im Grunde eine einzige Variable. Der Inhalt dieser Variable ist aber keine Zahl, auch kein Buchstabe oder ein Wahrheitswert, sondern die Adresse eines Abschnitts im Arbeitsspeicher des jeweiligen Gerätes.

Wenn man sich einmal den Spaß macht, diese Variable mit Hilfe des System.out.println()-Befehls auszugeben, dann erhält man einen Wert wie [I@78c75e93. Für einen Menschen völlig sinnfrei, für das Programm aber die Information, an welcher Stelle des Arbeitsspeichers die eigentlichen Daten stehen.

Wenn wir die 100 Zahlen des Arrays sehen wollen, müssen wir - wenn wir mit BlueJ arbeiten, einfach auf den gebogenen Pfeil im Objektinspektor klicken:

Der gebogene Pfeil im Objektinspektor wird angeklickt
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain

Es scheint so, dass jede der hundert int-Zahlen des Arrays den Wert 0 hat. Ob das jetzt eine Eigenart von BlueJ ist, kann ich Ihnen leider nicht sagen. Aber auf jeden Fall sollte man sich nicht darauf verlassen, dass das immer so ist - oder dass das in anderen Programmiersprachen auch so ist. Aber dazu kommen wir später.

Nachdem Sie sich davon überzeugt haben, dass das Programm einwandfrei funktioniert, wollen wir es jetzt mal gründlich auseinander nehmen.

3. Gründliche Analyse des Programms

3.1 Erzeugen eines Arrays aus 100 int-Zahlen

Betrachten wir zunächst die ersten Zeilen des Programms. Die Zeile 1 wurde hier noch nicht berücksichtig, auf die Anweisung in Zeile 1 kommen wir später.

Die Zeilen 3 bis 10 des Programms
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain

3.1.1 Deklaration des Arrays

In Zeile 5 finden wir die Deklaration des Arrays hundertZahlen.

Mit dieser Zeile teilen wir dem Programm mit, dass wir Speicherplatz für mehrere bis viele int-Zahlen benötigen.

Veranschaulichung der Deklaration des Arrays
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain

Bei dieser Deklaration des Arrays wird aber noch nicht gesagt, wie viele Zahlen im Arbeitsspeicher untergebracht werden sollen. Bis zu dieser Stelle "weiß" das Programm nur, dass wir nicht eine, sondern mehrere Zahlen des Typs int haben wollen. Der Bezeichner für den Zugriff auf diese Zahlen wird aber schon hier festgelegt: hundertZahlen.

3.1.2 Initialisierung des Arrays

Nachdem der Array deklariert wurde, muss er noch initialisiert werden. Das geschieht folgendermaßen:

hundertZahlen = new int[100];

Entscheidend sind hier das Schlüsselwort new sowie die Zahl 100.

Mit dem Schlüsswort new teilen wir mit, dass wir etwas Neues schaffen wollen. Durch die Angabe int sagen wir, wir wollen neue int-Variablen erzeugen (obwohl das ja eigentlich schon durch die Deklaration des Arrays geregelt wurde).

Die Zahl 100 in den eckigen Klammern teilt dem Programm mit, dass wir genau 100 dieser int-Zahlen erzeugen wollen.

Damit hätten wir unseren Array aus 100 int-Zahlen erzeugt.

3.2 Füllen des Arrays mit 100 Zufalls-Zahlen
3.2.1 Einen Zufallsgenerator erzeugen

Wenn wir sogenannte Zufallszahlen benötige, dann müssen wir die Klasse Random in unseren Java-Quelltext einbinden. Das geschieht in der ersten Zeile des Programms:

import java.util.Random;

Die Klasse Random stellt einige wichtige Methoden zur Erzeugung von zufälligen Zahlen zur Verfügung. Damit wir auf dieser Methoden zugreifen können, müssen wir zuerst ein Objekt dieser Klasse erzeugen. Das geschieht mit der Anweisung:

Random wuerfel = new Random();

Das Objekt der Klasse Random haben wir hier einfach wuerfel genannt.

3.2.2 Zufallszahlen erzeugen

Eine einzelne Zufallszahl vom Typ int können wir mit folgender Anweisung erzeugen:

x = wuerfel.nextInt(1000);

Die Variable x muss natürlich zuvor als int-Variable deklariert worden sein. Wenn wir der Methode nextInt() der Klasse Random den Wert 1000 übergeben, dann erzeugt nextInt() eine zufällige Zahl zwischen 0 und 999.

3.2.3 Den Array mit Zufallszahlen füllen

Wir wollen aber nicht nur eine Zufallszahl erzeugen, sondern 100. Das heißt, wir wollen alle 100 Elemente des Arrays mit einer Zufallszahl belegen. Das könnte so geschehen:

   hunderZahlen[ 0] = wuerfel.nextInt(1000)+1;
   hunderZahlen[ 1] = wuerfel.nextInt(1000)+1;
   hunderZahlen[ 2] = wuerfel.nextInt(1000)+1;
   hunderZahlen[ 3] = wuerfel.nextInt(1000)+1;
   hunderZahlen[ 4] = wuerfel.nextInt(1000)+1;
   ...
   hunderZahlen[99] = wuerfel.nextInt(1000)+1;

So kann man es natürlich auch machen, mit Hilfe der Zwischenablage kann man die Zeilen einfach kopieren und dann entsprechend ändern. Elegant ist das aber nicht. Wozu gibt es denn for-Schleifen? Schauen wir uns nun die Variante an, die wesentlich besser ist:

   for (int i=0; i<100; i++)
      hundertZahlen[i] = wuerfel.nextInt(1000)+1;

Achtung: Hat der Array 100 Elemente, so hat das erste Element den Index 0 (und nicht etwa den Index 1). Das letzte der 100 Elemente hat folglich nicht den Index 100, sondern den Index 99. Diese Eigenart der Arrays muss man sich gut einprägen, sonst sind Programmierfehler vorprogrammiert.

Warum muss noch eine 1 zu dem Zufallswert addiert werden?

Wir wollten Zahlen im Bereich zwischen 1 und 1000 haben. Mit

wuerfel.nextInt(1000);

erhalten wir aber Zahlen im Bereich zwischen 0 und 999. Also addieren wir zu dem Zufallswert einfach eine 1 dazu.

Hier noch einmal der komplette Quelltext zum Füllen des Arrays mit 100 Zufallszahlen:

Methode erzeugeArray()
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain

3.3 Suchen der kleinsten Zahl in dem Array

Wir finden die kleinste Zahl im Array, wenn wir folgendermaßen verfahren:

Nimm einfach mal an, dass die erste Zahl des Arrays die kleinste Zahl ist:

 int min = hundertZahlen[0];

Wir weisen der lokalen Variable min also den Wert des ersten Arrayelementes (Index = 0) zu.

Dann vergleichen wir das nächste Arrayelement mit dem Wert von min. Ist dieses kleiner als min, dann erhält min den Wert dieses kleineren Elements. Wenn das Arrayelement nicht kleiner ist als min, dann wird einfach mit dem nächsten Arrayelement weitergemacht:

for (int i=1; i<100; i++)
    if (hundertZahlen[i] < min)
        min = hundertZahlen[i];

Wenn der ganze Array durchsucht wurde, kann der Wert von min mit dem return-Befehl an die Methode zurück gegeben werden, die mini() aufgerufen hat.

return min;

Hier noch einmal der komplette Quelltext der Methode mini():

Die sondierende methode mini()
Autor: Ulrich Helmich 05/2025, Lizenz: Public domain

Theorieteil:

4. Was ist überhaupt ein Array?

Ein Array ist eine endliche Menge völlig gleichartiger Variablen. Unser Array aus dem obigen Programm besteht aus 100 int-Variablen. Genau so gut könnte man einen Array erzeugen, der aus 200 double-Variablen oder 2127 String-Variablen besteht.

4.1 Wie deklariert man einen Array?

Ein Array wird in einer Java-Klasse ähnlich wie ein normales Attribut deklariert. Vergleichen wir einmal die Deklaration einer einzelnen int-Variable und eines Arrays aus lauter int-Variablen:

int eineZahl;
int[] achtZahlen;

Der Array heißt zwar achtZahlen, die Arraygröße ist jedoch noch nicht festgelegt; das geschieht erst bei der Initialisierung des Arrays (s.u.). Auf die gleiche Weise könnte man auch einen Array aus double-Zahlen oder Strings deklarieren:

double[] zwanzigZahlen;
String[] textseite;
4.2 Was passiert bei der Deklaration?

Bei der Deklaration teilt man dem Rechner bzw. dem Java-System mit, dass man einen Array haben möchte, und wie der Array heißen soll. Nähere Angaben, vor allem wie viele Elemente der Array haben soll, hat man noch nicht gemacht.

Nach der Deklaration

int[] achtZahlen;

hat man zwar eine Variable erzeugt, die "achtZahlen" heißt, aber in der Variable steht noch nichts drin, sie ist leer.

Für Experten: Die Variable zeigt noch nicht auf einen konkreten Platz im Arbeitsspeicher.

4.3 Wie initialisiert man einen Array?

Bei der Initialisierung wird die Zahl der gewünschten Arrayelemente festgelegt.

achtZahlen = new int[8];

Offensichtlich will man hier acht int-Zahlen verwenden.

Für Experten: Die Variable achtZahlen zeigt jetzt auf einen bestimmten Bereich im Arbeitsspeicher, der so groß ist, dass genau acht int-Zahlen untergebracht werden können. Die erste Speicherzelle dieses Bereichs hat eine bestimmte Adresse, und diese Startadresse wird jetzt in der Variable achtZahlen gespeichert. Das kann man leicht ausprobieren.

public class KleinerTest
{
    int[] achtZahlen;
    
    public KleinerTest()
    {
       achtZahlen = new int[8];
       System.out.println(achtZahlen);
    }
}

Ausgegeben wird jetzt ein Wert wie [I@38638550. Das ist die Darstellung der Speicheradresse für den Array auf einem Apple-Rechner mit M1-Prozessor unter macOS Ventura. Bei einem Windows- oder Unix-Rechner wird es ähnlich aussehen.

4.4 Wie weist man einem Arrayelement Werte zu?
Ein Beispiel
achtZahlen[0] = 1;
achtZahlen[1] = 4;
achtZahlen[2] = 9;

Zur Zuweisung eines Wertes an ein Arrayelement benötigt man die relative Adresse dieses Elementes in dem Speicherbereich, in dem der Array liegt. Dazu dient der Index. Auf jedes Arrayelement kann direkt mithilfe des Index zugegriffen werden. Das erste Arrayelement hat immer den Index 0.

Weitere Beispiele mit ausführlichen Erläuterungen
zahl[0] = 13;

"zahl" ist hier der Bezeichner, 0 der Index, und 13 der Wert.

temperatur[12] = 27.3;

Hier heißt der Bezeichner "temperatur", der Index ist 12, und der zugewiesene Wert für das dreizehnte (!) Arrayelement ist 27.3.

inventar[2] = new Gegenstand("Hammer",0,45,2);

Der Bezeichner heißt hier "inventar", der Index ist 2, und der Wert für das dritte Element des Arrays ist nichts anderes als ein neues Objekt der Klasse Gegenstand. Dieses neue Objekt wird in dieser Programmzeile erst erzeugt, das sieht man ja an dem Wort "new" und dem Aufruf des Konstruktors der Klasse Gegenstand.

for (int k=0; k<max; k++) liste[k] = k*k+3*k-2;

Hier haben wir ein schönes Beispiel, wie man mit Hilfe von for-Schleifen (oder anderen Schleifen) den Umgang mit Arrays erleichtern kann. Weitere Informationen dazu finden Sie auf der Spezialseite "Arrays und for-Schleifen".

4.5 Wie greift man auf den Wert von Arrayelementen zu?
Hier ein paar Beispiele
System.out.println(zahl[3]);

Ein Arrayelement kann mit dem println()-Befehl ausgegeben werden.

int ergebnis = zahl[2];

Den Wert eines Arrayelements kann man einer anderen Variablen zuweisen, die dann aber den gleichen Datentyp haben muss wie die Arrayelemente.

int summe = zahl[0] + zahl[1] + zahl[2];

Man kann mehrere Arrayelemente gleichzeitig auswerten.

if (zahl[1] < 0) 
			zahl[1] = 0;

Man kann innerhalb von if-Abfragen, while-Schleifen etc. auf den Wert bestimmter Arrayelemente zugreifen.

inventar[4].ausgeben();

In einem Objekt-Array kann auf die einzelnen Objekte zugegriffen werden, man kann sogar Methoden dieser Objekte aufrufen und ausführen lassen. Hier wird die ausgeben()-Methode des fünften Elementes des Arrays inventar aufgerufen. Das ist möglich, weil jedes Arrayelement ein eigenes Objekt mit Attributen und Methoden ist.

Weitere Beispiele mit ausführlichen Erläuterungen
int y = zahl[0];

Das erste Arrayelement wird ausgelesen, der ausgelesene Wert wird dann an die int-Variable y überwiesen. Also hat y hinterher den gleichen Wert wie das erste Arrayelement.

System.out.println(temperatur[12]);

Das 13. Arrayelement (Index 12) wird ausgelesen, der ausgelesene Wert wird dann an den System.out.println()-Befehl übergeben und in das Konsolenfenster ausgegeben.

if (zahlenliste[4] >= 20)
   bedingung = true;
else
   bedingung = false;

Das fünfte Arrayelement wird ausgelesen und mit der Zahl 20 verglichen. Wenn der Wert dieses Arrayelementes größer oder gleich 20 ist, so wird die Variable bedingung - offenbar eine boolean-Variable - auf den Wert true gesetzt. Ist dies nicht der Fall, erhält bedingung den Wert false.

bedingung = (zahlenliste[4] >= 20);

Diese Anweisung macht exakt das Gleiche wie die vier Zeilen des vorherigen Beispiels. Der Ausdruck zahlenliste[4] >= 20 ist eine logische Bedingung, also entweder true oder false. Egal, welchen Wert diese Bedingung hat, das Ergebnis wird dann an die Variable bedingung überwiesen.

inventar[3].beschaedigen(20);

Der Array inventar speichert Objekte der Klasse Gegenstand - was man hier nicht gleich sieht. Jedes Objekt hat nicht nur Attribute, sondern auch Methoden. Diese Anweisung greift auf die Methode beschaedigen() des vierten Objektes des Arrays inventar zurück und ruft diese Methode mit dem Parameter 20 auf. Das vierte Objekt soll also um den Wert 20 beschädigt werden.

5. Arrays als Parameter von Methoden

Man kann Arrays als Attribute von Klassen verwenden. In unserem einführenden Beispiel mit den 100 Zahlen haben wir das auch gemacht. Dieses Vorgehen hat den Vorteil, dass alle Methoden der Klasse schreibend und lesend auf die Elemente des Arrays zugreifen können.

Manchmal will man aber auch einfach eine unabhängige und universell einsetzbare Methode schreiben, die eine Operation auf einen beliebigen int- oder double-Array ausführt (oder auf Arrays mit anderen Elementtypen). Wenn eine solche Methode wirklich unabhängig von einer bestimmten Klasse sein soll, darf man innerhalb der Methode nicht auf einen Array mit einem konkreten Namen zugreifen. Die Methode weiß ja noch gar nicht, wie der Array heißt, den sie bearbeiten oder auswerten soll. Außerdem soll die Methode auf viele verschiedene Arrays mit unterschiedlichen Namen zugreifen können. Erst dann ist die Methode universell als Werkzeug einsetzbar. Betrachten wir einmal, wie eine solche universelle Methode aufgebaut sein könnte:.

   public int mini(int[] zahlen)
   {
      int mini = zahlen[0];

      for (int i=1; i < zahlen.length; i++)
         if (zahlen[i] < mini)
            mini = zahlen[i];

      return mini;
   }

Das ist fast der gleiche Quelltext wie in unserem Einführungsbeispiel mit den 100 Zahlen. Allerdings heißt der Parameter jetzt nicht mehr hundertZahlen, sondern einfach nur zahlen, weil ja eine beliebige Anzahl von Arrayelementen übergeben werden kann. Das hängt ja davon ab, welche andere Methode mini() aufruft.

Der Kopf der Methode

public int mini(int[] zahlen)

hat einen formalen Parameter von Typ int[] namens zahlen, erwartet also beim Aufruf einen aktuellen Parameter ebenfalls vom Typ int[], dessen Name aber völlig egal ist.

Angenommen, wir haben in der Klasse oder in einer anderen Methode einen Array namens hundertZahlen deklariert und initialisiert und außerdem noch mit Zahlen gefüllt, dann können wir diese neue Methode wie folgt aufrufen:

int m = mini(hundertZahlen)

Der Array hundertZahlen wird also als aktueller Parameter an die Methode übergeben. Die gefundene kleinste Zahl wird dann an die lokale Variable m überwiesen.

Seitenanfang -
Weiter mit "Einfache Arrays, Teil 2"...