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

7.1 Einfache Arrays, Teil 1

Arrays - Objekt-Arrays - Verstehen - besser verstehen - bunte Kreise

Einführendes Beispiel

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

Programm 1
public class Zahlen 
{

   public int mini(int a, int b) 
   {
      if (a < b)
         return a;
      else
         return b;
   }
}

Wenn der erste Parameter kleiner ist als der zweite, wird er als die "kleinste Zahl" interpretiert und zurückgeliefert. Ist der erste Parameter nicht kleiner als der zweite, wird der zweite Parameter als "kleinste Zahl" zurückgeliefert, selbst dann, wenn er genau so groß ist wie der erste Parameter.

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

Programm 2
public class Zahlen 
{

   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 geschaut, 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.

Wenn wir die Methode auf vier Parameter erweitern, wird der Quelltext noch länger und unübersichtlicher, über fünf oder sechs Parameter wollen wir gar nicht mehr nachdenken.

Betrachten Sie nun folgende Methode, welche das Minimum von 10 Zahlen ermittelt und zurückliefert.

Programm 3
   public int mini(int[] zehnZahlen)
   {
      int mini = zehnZahlen[0];

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

      return mini;
   }

Hier werden zehn Zahlen gleichzeitig als Parameter übergeben! Wie geht denn das? Um das zu verstehen, müssen wir uns mit sogenannten Arrays beschäftigen. Kurz gesagt, sind Arrays "Bündel" aus einer beliebigen endlichen Anzahl gleichartiger Variablen, zum Beispiel von zehn int-Zahlen. Wie man Arrays deklariert und initialisiert, werden wir gleich noch genauer sehen. Bleiben wir zunächst bei unserem Beispiel.

In der Zeile

      int mini = zehnZahlen[0];

wird der Wert des ersten Arrayelements (also der ersten Zahl des "Bündels") in die lokale Variable mini kopiert. Angenommen, das erste Arrayelement hat den Wert 7, so erhält mini nun diesen Wert 7 zugewiesen. Das erste Arrayelement hat übrigens nicht die "Hausnummer" 1, sondern die "Hausnummer" 0. In der Fachsprache sagt man allerdings nicht "Hausnummer", sondern Index. Der Index des ersten Arrayelements ist immer Null.

Nun kommt eine for-Schleife, in der die restlichen neun Arrayelemente untersucht werden. Die Zahl der Arrayelement ist in dem Attribut length gespeichert, das jeder Array besitzt.

Angenommen, das Arrayelement mit dem Index 1 hat den Wert 5. Dann ist die Bedingung

         if (zehnZahlen[1]) < mini)

erfüllt, denn offensichtlich ist 5 < 7. Das heißt, die lokale Variable mini erhält einen neuen Wert zugewiesen, nämlich 5.

Die dritte Zahl des Arrays soll den Wert 12 besitzen. Jetzt ist die Bedingung

         if (zehnZahlen[2]) < mini)

nicht erfüllt, denn 12 ist nicht kleiner als 5. Also wird der Wert von mini nicht aktualisiert, stattdessen wird das nächste Arrayelement untersucht. Wenn beispielsweise der Arrayelement mit dem Index 7 den Wert 3 hat, ist die Bedingung wieder erfüllt, und in mini wird der neue Wert 3 gespeichert.

Schließlich wird das letzte Arrayelement untersucht, und die for-Schleife terminiert (wird also beendet). In mini ist jetzt tatsächlich der Wert des kleinsten Arrayelements gespeichert. Daher wird in der letzten Zeile der Methode der Wert von mini als Ergebnis der sondierenden Methode zurückgeliefert.

Das Schöne an der Sache ist folgendes: Der Parameter der Methode heißt zwar zehnZahlen, aber theoretisch kann der übergebene Array beliebig viele Zahlen enthalten, also auch 100, 1000 oder mehr. Vielleicht sollte man den Parameter daher nicht "zehnZahlen" nennen, sondern allgemein "zahlen".

Nach diesen einführenden Betrachtungen kommen wir nun zum eigentlichen Hauptthema dieser Seite, nämlich Arrays.

Was ist überhaupt ein Array?

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

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;
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.

Wie initialisiert man einen Array?

Bei der Initialisierung wird die Zahl der gewünschten Array-Elemente festgelegt.

achtZahlen = new int[8];

Offensichtlich will man hier acht int-Zahlen verwenden.

Wie weist man einem Array-Element Werte zu?
Ein Beispiel
achtZahlen[0] = 1;
achtZahlen[1] = 4;
achtZahlen[2] = 9;

Zur Zuweisung eines Wertes an ein Array-Element benötigt man die Adresse dieses Elementes. Dazu dient der Index. Auf jedes Array-Element kann direkt mithilfe des Index zugegriffen werden. Das erste Array-Element 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 ist 27.3.

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

Der Bezeichner heißt hier "inventar", der Index ist 2, und der Wert 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".

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

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

int ergebnis = zahl[2];

Den Wert eines Array-Elements kann man einer anderen Variablen zuweisen.

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

Man kann mehrere Array-Elemente gleichzeitig auswerten.

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

Man kann innerhalb von if-Abfragen, while-Schleifen etc. auf den Wert bestimmter Array-Elemente 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 Array-Element ein eigenes Objekt mit Attributen und Methoden ist.

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

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

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

Das 13. Array-Element (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 Array-Element wird ausgelesen und mit der Zahl 20 verglichen. Wenn der Wert dieses Array-Elementes 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.

Arrays als Parameter von Methoden

Man kann Arrays als Attribute von Klassen verwenden. Das 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 Methode schreiben, die einen Array als Parameter bekommt, so dass sie diesen Array analysieren oder sogar verändern kann. In unserem dritten Beispiel aus der Einleitung sollte eine Methode mini den kleinsten Wert eines Arrays aus int-Zahlen ermittlen und zurückliefern.

   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 Programm 3. Allerdings heißt der Parameter jetzt nicht mehr "zehnZahlen", sondern einfach nur "zahlen", weil ja eine beliebige Anzahl von Arrayelementen übergeben werden kann.

Die Deklaration des Parameters beginnt genau so wie die Deklaration eines Array-Attributs, nämlich mit der Nennung des Datentyps (hier int) und einem Paar eckiger Klammern, gefolgt von dem Namen des Arrays.

Innerhalb der Methode kann dann auf die einzelnen Elemente des Arrays lesend und schreibend zugegriffen werden, wie bereits weiter oben erklärt.

 

Arrays als Rückgabewerte sondierende Methoden

Oft hat man beim Programmieren das Problem, dass eine sondierende Methode nur einen einzigen Wert zurückliefern kann. Eine Methode wie

public int mini()

liefert immer nur eine int-Zahl als Ergebnis zurück, nicht zwei oder drei int-Zahlen.

Angenommen, in einem kleinen Java-Spiel soll eine Methode die Koordinaten eines Monsters zurückliefern. Hier gibt es mehrere Wege wie man das erreichen kann.

Möglichkeit 1

Sie schreiben zwei sondierende Methoden

public int gibXWert()
public int gibYWert()
Möglichkeit 2

Sie deklarieren eine eigene Klasse Koordinaten. Jedes Objekt dieser Klasse besitzt zwei Attribute, nämlich xWert und yWert vom Typ int. Dann können Sie die Methode so formulieren:

public Koordinaten gibKoordinaten()
Möglichkeit 3

Jetzt kommen die Vorzüge von Arrays ins Spiel. Sie schreiben die Methode so, dass ein aus zwei int-Zahlen bestehender Array zurückgeliefert wird:

public int[] gibKoordinaten()
{
   int[] temp = new int[2];
   temp[0] = xWert;
   temp[1] = yWert;
   return temp;
}

Diesen Array müssen Sie natürlich in der Methode erst als lokale Variable erzeugen. In dem ersten Arrayelement wird nun der xWert des Monsters gespeichert, in dem zweiten Arrayelement der yWert. Anschließend wird der ganze Array mittels return als Ergebnis zurückgeliefert. Auf diese Weise haben Sie zwei Werte gleichzeitig zurückgegeben. Dieses Verfahren ist natürlich nicht auf zwei Werte beschränkt. Sie können den lokalen Array beliebig groß machen. Wenn Sie wollen, können Sie also auch hundert oder tausend Werte auf einmal zurückliefern.

Weiter mit Objekt-Arrays...