Wir wollen 10 Preise einlesen und den niedrigsten markieren:
19.95 23.95 24.95 18.95 <- niedrigster Preis 29.95 19.95 20.00 22.99 24.95 19.95
Alle Daten müssen eingelesen werden, bevor wir ausgeben können, daher müssen wir sie zwischenspeichern. Dafür zehn Variablen zu verwenden wäre sehr unflexibel. Was nun?
Durch
double[] data = new double[10];
deklarieren wir ein Array von Double-Werten der Größe 10.
Genauer:
typ[]
ist der Typ der Arrays mit Einträgen vom Typ typ
.new typ[n]
liefert ein frisches Array vom Typ typ
der Länge n
zurück. Hier ist n
ein Ausdruck vom Typ double
.
Im Beispiel ist also data
eine Arrayvariable, die ein frisches Array vom Typ double
der Länge 10 enthält.
Im Rechner ist der Arrayinhalt als Block aufeinanderfolgender Speicherzellen repräsentiert. Das Array selbst ist ein Objekt, bestehend aus der Länge und der Speicheradresse des Blocks.
Felder
erstellen, welches das Array aus obigem Beispiel enthält. Anschließend mit dem Objekt-Inspektor inspizieren und obige Erklärung nachvollziehen…Durch
data[4] = 29.95;
setzen wir das Fach mit der Nummer 4 auf den Wert 29.95. Mit
System.out.println("Der Preis ist EUR" + data[4]);
können wir diesen Wert ausgeben.
data[4]
verhält sich ganz genauso wie eine "normale" Variable vom Typ double
.
Ist a
ein Array und i
ein Ausdruck des Typs int
, so bezeichnet a[i]
das Fach mit Index i
des Arrays a
.
Achtung: Diese Indizes beginnen bei Null (wie bei den Strings auch!). Es muss also i
echt kleiner (eins weniger) als die Länge von a
sein.
Im Beispiel sind die Fächer also
data[0], data[1], data[2], data[3], ... , data[9]
Ist a
ein Array, so ist
a.length
die Länge des Arrays als Integer. (Achtung: nicht a.length()
!!!)
Das ist nützlich, wenn man die Länge später (durch Editieren und Neukompilieren) vergrößern muss. a.length
stellt sich dann automatisch mit um. Ein "festverdrahteter" Wert wie 10 müsste auch explizit umgeändert werden.
Die Länge wird abgerufen wie eine als public
deklarierte (Instanz)variable. Man kann sie aber im Programm nicht verändern, d.h.
a.length = 20;
ist nicht erlaubt.
new
erzeugt; die Länge des Arrays wird in eckigen Klammern angegeben.=
einen neuen Wert zuweisen..length
Merke: Das "Durcharbeiten" eines Arrays erfolgt meist so:
for(int i = 0; i < a.length; i++) { ... // Bearbeiten des Faches mit Index i ... }
double[] data; System.out.println(data[5]);
ist falsch. data[5]
wurde ja nicht initialisiert.
double[] data; data[5] = 7; System.out.println(data[5]);
ist aber auch falsch!
Der Grund ist, dass die Variable data
selber noch gar nicht initialisiert wurde.
Man muss so einer Variable erst ein Array (= Verweis auf Folge von Variablen) zuweisen. Normalerweise macht man das mit new
:
double[] data; data = new double[10];
Man kann aber auch direkt einen Arrayausdruck zuweisen, z.B.
double[] data = {0,1,2,3,4,5,6,7,8,9};
Eine Array kann als Parameter übergeben werden:
public double mittelwert(double[] zahlen) { if (zahlen.length == 0) { return 0.0; } double summe = 0; for(int i = 0; i < zahlen.length; i++) { summe = summe + zahlen[i]; } return summe/zahlen.length; }
Man kann nun etwa mittelwert(data)
aufrufen. Wert ist der Mittelwert von data
.
Ein Arraytyp kann auch als Rückgabewert in Erscheinung treten. Hier ist eine Methode, die die Eckpunkte eines regelmäßigen n-Ecks zurückgibt:
/* Gibt die einzelnen Eckpunkte eines regelmäßigen Polygons mit * n Ecken, * dem Mittelpunkt zentrum und * Radius radius * aus */ public getPunkt[] nEck(int n, Punkt zentrum, double radius) { Punkt[] result = new Punkt[n]; // Berechnung mit sin und cos // ... bitte ergänzen... // anschließend Rückgabe des Punkte-Arrays return result; }
Man möchte wissen, ob einer der eingelesenen Preise ≤ 1000
ist:
boolean gefunden = false; for(int i = 0; i < data.length; i++) gefunden = gefunden || (data[i] <= 1000); // wer das erklären kann, ist gut!
jetzt ist gefunden true
genau dann, wenn data
einen Eintrag ≤ 1000
hat. Man möchte nun auch noch wissen, wie viele Preise ≤ 1000
sind:
int count = 0; for(int i = 0; i < data.length; i++) if (data[i] <= 1000) count++;
Jetzt ist count
gleich der Anzahl derjenigen Preise, die ≤ 1000
sind.
Man möchte den Eintrag an der Stelle pos
aus einem teilweise gefüllten Array löschen.
Falls die Ordnung keine Rolle spielt:
// Definition für die intern benutzte Länge: dataSize = data.length; // Das zu löschende Element an der Stelle pos // mit dem letzten Element überschreiben data[pos] = data[dataSize-1]; // die intern verwendete Längenangabe reduzieren dataSize = dataSize - 1; // Achtung: data.length hat sich nicht verändert!
Falls die Ordnung beibehalten werden muss:
// Elemente bis zur Position aufschieben for(int i = pos; i < dataSize - 1; i++) data[i] = data[i+1]; // die intern verwendete Längenangabe reduzieren dataSize = dataSize - 1;
…an der Stelle pos unter Beibehaltung der Ordnung:
for(int i = dataSize; i > pos; i--) data[i] = data[i-1]; data[pos] = neuerWert; dataSize = dataSize + 1;
Man muss sich immer wieder sehr genau klar machen, was hier passiert.
In der Anwendung muss man natürlich sicherstellen, dass pos
nicht außerhalb der Grenzen liegt.
Arrays können auch als Instanzvariablen eines Objektes in Erscheinung treten. Es empfiehlt sich, dann im Konstruktor auch gleich ein frisches Array zu erzeugen.
Beispiel:
public class Polygon { private int n; // Zahl der Ecken private Point[] ecken; // Liste der Ecken /* Methoden und Konstruktoren */ }
Die Einträge eines Arrays können wieder Arrays sein. Das gibt ein zweidimensionales Array.
int[][] einmaleins = new int[10][10]; for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { einmaleins[i][j] = (i+1) * (j+1); } }
int[] v = new int[10]; for(int i = 1; i <= 10; i++) v[i] = v.length - i;
Was steht nach erfolgreicher Ausführung der Schleife im Array? (Bitte selbst durchspielen und nicht laufen lassen…)
int[]
hat, der modifiziert wird.int[]
hat, der nicht modifiziert wird.int[]
zurückgibt.1 4 9 16 25 36 49 64 81 100