Reihungen in Java
Diese Lektion behandelt nur grundlegende Aspekte des Themas der Reihungen, wie man sie bereits ohne Kenntnisse der objektorientierten Programmierung verstehen kann. Weitere Aspekte des Themas können dann durch das Erlernen der objektorientierten Programmierung erlernt werden.
Reihungen
- Eine Variable ist ein Speicherplatz für einen Wert eines bestimmten Datentyps.
- Eine Reihung ist eine Variable, die ihrerseits selber wiederum eine bestimmte Anzahl von Variablen enthält.
Reihung mit sechs Variablen
.-------------.-------------.-------------.-------------.-------------.-------------.
| Variable 0 | Variable 1 | Variable 2 | Variable 3 | Variable 4 | Variable 5 |
'-------------'-------------'-------------'-------------'-------------'-------------'- Diese Variablen werden die Komponenten der Reihung genannt
- Die Komponenten haben keine eigenen Namen. Man stellt sich vor, daß sie in einer linearen Abfolge hintereinander angeordnet sind. Sie können daher unter Angabe ihrer Reihung und ihrer Position in der Reihung angegeben werden.
- Alle Komponenten einer Reihung haben denselben Typ, welcher Komponententyp der Reihung genannt wird.
- Nennt man den Komponententyp einer Reihung T, dann wird der Typ der Reihung selber als T [] geschrieben. (Beispielsweise ist »int[]« der Typ einer Reihung mit int-Komponenten.)
Eine Reihung von Variablen ermöglicht es, mehrere Variablen des gleichen Typs als eine Einheit anzusehen.
- Aussprachehinweis
- array əˈreɪ (c)
Beispiel Der Parameter der Hauptmethode
In dem folgenden Programm wird mit »final java.lang.String[] args« eine Reihung mehrerer java.lang.String -Variablen als Parameter namens »args« deklariert.
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{} }
Die Anzahl der Komponenten der Reihung »args« ist »args.length«.
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( args.length ); }}- java.lang.System.out
0
Die Werte der Reihung können beim Aufruf der virtuellen Java-Maschine nach dem Klassennamen angegeben werde.
- Startkommando
java Main alpha beta gamma
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( args.length ); }}- java.lang.System.out
3
⚠ »args« ist kein Schlüsselwort der Programmiersprache Java, sondern ein vom Programmierer gewählter Name des Hauptmethodenparameters, welcher genausogut auch anders benannt werden könnte.
- Main.java
public class Main
{ public static void main( final java.lang.String[] tisch )
{ java.lang.System.out.println( tisch.length ); }}
Ausgabe von Reihungen
Um die Reihung verständlich auszugeben, muß sie erst mit »java.util.Arrays.toString« in einen Text gewandelt werden.
- Aussprache des Wortes “array ”
array əˈre, əˈreɪ
- Startkommando
java Main alpha beta gamma
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println
( java.util.Arrays.toString( args )); }}java.lang.System.out
[alpha, beta, gamma]
Die einzelnen Variablen einer Reihung nennen wir auch die Komponenten der Reihung.
Zugriffe auf einzelne Komponenten einer Reihung
Die Komponenten einer Reihung sind durchnumeriert: Dabei wird bei 0 begonnen, so daß die erste Komponente einer Reihung also die Kennzahl 0 hat.
Die Kennzahl einer Komponente nennt man auch den Index dieser Komponente (Plural: Indizes, Verb: indizieren), wir sprechen hier auch von der Position der Komponente.
Eine Reihung muß aber nicht unbedingt überhaupt Komponenten enthalten. Sie kann auch leer sein. Dann hat sie null Komponenten, und es gibt keine erste Komponente.
Zur Angabe einer bestimmten Komponente wird die Reihung angegeben und dahinter die Position der Komponente in eckigen Klammern notiert.
Bei einer Reihung names »args« ist die erste Komponente »args[ 0 ]«, falls diese Reihung überhaupt mindestens eine Komponente besitzt.
Bei einer Reihung names »args« ist die letzte Komponente »args[ args.length - 1 ]«, falls diese Reihung überhaupt mindestens eine Komponente besitzt.
Bei einer Reihung names »args« ist die zweite Komponente »args[ 1 ]«, falls diese Reihung überhaupt mindestens zwei Komponenten besitzt.
Syntax (vereinfacht)
- Die Indizierung
Ausdruck
.----------. .-. .----------. .-.
--->| Ausdruck |--->( [ )--->| Ausdruck |--->( ] )--->
'----------' '-' '----------' '-'
Der Operator »[« »]« wird oft als ein Postfix-Operator angesehen, obwohl sein zweiter Operand dabei nicht richtig gewürdigt wird.
Typen (vereinfacht)
Vor der ersten eckigen Klammer »[« muß eine Reihung angegeben werden.
Hinter der ersten eckigen Klammer »[« muß eine ganze Zahl angegeben werden, welche die Position einer Komponente der Reihung angibt.
Der Typ des gesamten Ausdrucks ist der Komponententyp der angegebenen Reihung.
Prioritäten (vereinfacht)
- Priorität und Assoziativität der bisher behandelten Operatoren
() Eingeklammerter Ausdruck
(arglist) [n] Aufrufoperator, unaere nachgestellte Operatoren
+ - Unaere vorangestellte Operatoren
L * / Multiplikation, Division, Divisionsrest
L + - Addition, Subtraktion
R = Zuweisung
Beispiele
- Startkommando
java Main alpha beta gamma
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( args[ 0 ]); }}- java.lang.System.out
alpha
- Startkommando
java Main alpha beta gamma
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( args[ 1 ]); }}- java.lang.System.out
beta
- Startkommando
java Main alpha beta gamma
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( args[ 2 ]); }}- java.lang.System.out
gamma
- Startkommando
java Main alpha beta gamma
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( args[ args.length - 1 ]); }}- java.lang.System.out
gamma
Anlegen einer neuen Reihung
Eine Reihung kann auch als lokale Variable neu angelegt werden,
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ final int[] a ={ 8, 4, 2, 2, 2 }; }}
Obwohl die Schreibweise »{ 8, 4, 2, 2, 2 }« etwas an einen Block erinnert, handelt es sich dabei nicht um einen Block. Die geschweiften Klammern enthalten hier vielmahr die Anfangswerte der einzelnen Komponenten. Die Anzahl der Komponenten wird daraus hergeleitet.
Die Schreibweise mit den geschweiften Klammern kann so nur bei der Initialisierung einer Reihung verwendet werden, sie kann nicht an anderen Stellen eines Programms verwendet werden, um eine bestimmte Reihung anzugeben.
Schreiben in eine Reihung
Eine Komponente einer Reihung kann auch als linke Seite einer Zuweisung verwendet werden.
- Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ final int[] a ={ 0, 0, 0, 0, 0 };
java.lang.System.out.println( java.util.Arrays.toString( a ));
a[ 1 ]= 4;
java.lang.System.out.println( java.util.Arrays.toString( a )); }}java.lang.System.out
[0, 0, 0, 0, 0]
[0, 4, 0, 0, 0]
Reihungen als Parameter ⃗
Hat eine Methode eine Reihung als Argument erhalten, kann sie deren Komponenten ändern!
- Main.java
public final class Main
{
public static void m( final int[] a ){ a[ 3 ]= 3; }
public static void main( final java.lang.String[] args )
{ final int[] a ={ 0, 0, 0, 0, 0 };
java.lang.System.out.println( java.util.Arrays.toString( a ));
m( a );
java.lang.System.out.println( java.util.Arrays.toString( a )); }}java.lang.System.out
[0, 0, 0, 0, 0]
[0, 0, 0, 3, 0]
Soll eine Variable so an eine Methode übergeben werden, daß die Methode jene Variable ändern kann, ist es also möglich, diese Variable als Komponente einer Reihung zu übergeben.
public final class Main
{public static void m( int[] v ){ v[ 0 ]= 27; }
public static void main( final java.lang.String[] args )
{ final int[] v ={ 0 };
java.lang.System.out.println( java.util.Arrays.toString( v ));
m( v );
java.lang.System.out.println( java.util.Arrays.toString( v )); }}[0]
[27]
Reihungen als Rückgabewerte ⃗
Falls mehrere Werte von einer Methode zurückgegeben werden sollen, so können diese als Reihung zurückgegeben werden.
public final class Main
{public static int[] m()
{ int[] e ={ 2, 7 };
return e; }public static void main( final java.lang.String[] args )
{ final int[] e = m();
java.lang.System.out.println( e[ 0 ]);
java.lang.System.out.println( e[ 1 ]); }}
Erzeugung von Reihungen ⃗
Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{java.lang.System.out.println( java.util.Arrays.toString
( new int[ 10 ] ));java.lang.System.out.println( java.util.Arrays.toString
( new int[]{ 1, 2, 3 } ));java.lang.System.out.println( java.util.Arrays.toString
( new java.lang.String[]{ "abc", "def", "ghi" } )); }}transcript
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 2, 3]
[abc, def, ghi]Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{java.lang.System.out.println( java.util.Arrays.toString
( new java.lang.String[ 10 ] )); }}transcript
[null, null, null, null, null, null, null, null, null, null]
Übersetzung
Main.java
public final class Main
{ public static void print( final int a )
{ final java.lang.String[] deutsch = { "Null", "Eins", "Zwei", "Drei", "Vier" };
java.lang.System.out.println( a + " ist " + deutsch[ a ]+ "." ); }public static void main( final java.lang.String[] args )
{ print( 0 ); print( 1 ); print( 2 ); print( 3 ); print( 4 ); }}transcript
0 ist Null.
1 ist Eins.
2 ist Zwei.
3 ist Drei.
4 ist Vier.
Übungsfragen
- ? Welche Ausgabe erzeugt das folgende Programm?
public class Main
{ public static void main( final java.lang.String[] args )
{ final int[] a ={ 4, 3, 2, 1, 0, 1, 2, 3, 4 };
java.lang.System.out.println( a[ 0 ] );
java.lang.System.out.println( a[ a[ 0 ]] );
java.lang.System.out.println( a[ a[ 3 ]- 1 ] ); }}
Übungsaufgaben
- / Einlesen
- Schreiben Sie ein Programm, das die Person begrüßt, deren Vorname beim Aufruf des Programms als erstes Argument übergeben wird.
- Wenn das Programm beispielsweise mit »java Main Marie« aufgerufen wird, dann soll es ausgeben »Hallo, Marie!«.
- Zusatzanforderung: Falls kein Name beim Aufruf als Argument angegeben wird, soll das Programm »Hallo, Welt!« ausgeben.
- Zusatzanforderung: Falls mehrere Namen angegeben werden, wie etwa bei »java Main Marie Paul Sophia«, dann soll das Programm alle Personen in sprachlich korrekter Weise begrüßen, wie beispielsweise mit »Hallo, Marie, Paul und Sophia!«.
- / Vertauschen
- Schreiben Sie eine Methode, welche eine int -Reihung als Argument akzeptiert und die ersten beiden Komponenten dieser Reihung miteinander vertauscht.
- ⚠ Bei dieser Aufgabe soll eine Methode geschrieben werden (und damit ist nicht die Hauptmethode des Programmes gemeint, sondern die in der Aufgabenstellung beschriebene Methode). Es wäre keine richtige Lösung, nur eine Anweisungsfolge zu schreiben, welche die ersten beiden Komponenten einer Reihung miteinander vertauscht.
- Anmerkung Diese Übungsaufgabe gehört zum roten Faden „Vertauschen“.
- Main.java
public final class Main
{…
public static void main( final java.lang.String[] args )
{ final int[] a = { 4, 3, 5 };
java.lang.System.out.println( java.util.Arrays.toString( a ));
vertauschenDerErstenBeidenKomponentenVon( a );
java.lang.System.out.println( java.util.Arrays.toString( a ));
final int[] b = { 2, 6, 1, 8 };
java.lang.System.out.println( java.util.Arrays.toString( b ));
vertauschenDerErstenBeidenKomponentenVon( b );
java.lang.System.out.println( java.util.Arrays.toString( b )); }java.lang.System.out
[4, 3, 5]
[3, 4, 5]
[2, 6, 1, 8]
[6, 2, 1, 8]- / Sekundenwandlung
- Schreiben Sie eine Methode, welche eine ganz Zahl von Sekunden als Argument mit der Bedeutung einer Zeitdauer akzeptiert und als Ergebnis die in Stunden, Minuten und Sekunden gewandelte Länge dieser Zeitdauer liefert. Für die Rückgabe dieser drei Werte soll eine Reihung mit drei Komponenten verwendet werden. Beispiel: 10118 Sekunden sind zwei Stunden, 48 Minuten, und 38 Sekunden.
- ⚠ Bei dieser Aufgabe soll eine Methode geschrieben werden (und damit ist nicht die Hauptmethode des Programmes gemeint, sondern die in der Aufgabenstellung beschriebene Methode). Es wäre keine richtige Lösung, nur eine Anweisungsfolge zu schreiben, welche Sekunden in Stunden, Minuten und Sekunden zerlegt.
Zusatzfragen
- ? Zusatzfrage Welche Ausgabe erzeugt das folgende Programm? *
public class Main
{ public static void main( final java.lang.String[] args )
{ final int[] a ={ 4, 3, 2, 1, 0, 1, 2, 3, 4 };
java.lang.System.out.println( a[ 0 ]++ );
java.lang.System.out.println( a[ a[ 0 ]++ ]++ );
java.lang.System.out.println( a[ a[ a[ 0 ]++ ]++ ]++ ); }}
Mehrdimensionale Reihungen
In Java gibt es keine mehrdimensionalen Reihungen. Mehrdimensionale Reihungen lassen sich aber als Reihungen von Reihungen nachbilden.
Main.java
/**/
public final class Main
{
public static void main( final java.lang.String[] args )
{ final java.lang.String[][] a =
{ { "A", "B", "C", "D" },
{ "a", "b", "c", "d" } };
int zeile; int spalte;
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 0 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 1 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 2 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 3 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 0 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 1 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 2 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 3 ]);
java.lang.System.out.println( java.util.Arrays.toString( a[ zeile = 0 ]));
java.lang.System.out.println( java.util.Arrays.toString( a[ zeile = 1 ])); }}transcript
A
B
C
D
a
b
c
d
[A, B, C, D]
[a, b, c, d]
Die Anzahl der Spalten verschiedener Zeilen muß nicht gleich sein.
Main.java
/**/
public final class Main
{
public static void main( final java.lang.String[] args )
{ final java.lang.String[][] a =
{ { "A", "B", "C", "D" },
{ "a", "b" } };
int zeile; int spalte;
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 0 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 1 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 2 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 3 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 0 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 1 ]);
java.lang.System.out.println( java.util.Arrays.toString( a[ zeile = 0 ]));
java.lang.System.out.println( java.util.Arrays.toString( a[ zeile = 1 ])); }}transcript
A
B
C
D
a
b
[A, B, C, D]
[a, b]
Der new-Ausdruck unterstützt mehrdimensionale Reihungen insofern, als daß er alle Zeilen und Spalten bereitstellen kann.
Main.java
/**/
public final class Main
{
public static void main( final java.lang.String[] args )
{ final int anzahl_der_zeilen;
final int anzahl_der_spalten;final java.lang.String[][] a
= new java.lang.String[ anzahl_der_zeilen = 2 ][ anzahl_der_spalten = 4 ];int zeile; int spalte;
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 0 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 1 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 2 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 3 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 0 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 1 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 2 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 3 ]);
java.lang.System.out.println( java.util.Arrays.toString( a[ zeile = 0 ]));
java.lang.System.out.println( java.util.Arrays.toString( a[ zeile = 1 ])); }}transcript
null
null
null
null
null
null
null
null
[null, null, null, null]
[null, null, null, null]
Hier dasselbe manuell nachgebildet.
Main.java
/**/
public final class Main
{
public static void main( final java.lang.String[] args )
{ final int anzahl_der_zeilen;
final int anzahl_der_spalten;final java.lang.String[][] a
= new java.lang.String[ anzahl_der_zeilen = 2 ][];
a[ 0 ] = new java.lang.String[ anzahl_der_spalten = 4 ];
a[ 1 ] = new java.lang.String[ anzahl_der_spalten ];int zeile; int spalte;
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 0 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 1 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 2 ]);
java.lang.System.out.println( a[ zeile = 0 ][ spalte = 3 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 0 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 1 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 2 ]);
java.lang.System.out.println( a[ zeile = 1 ][ spalte = 3 ]);
java.lang.System.out.println( java.util.Arrays.toString( a[ zeile = 0 ]));
java.lang.System.out.println( java.util.Arrays.toString( a[ zeile = 1 ])); }}transcript
null
null
null
null
null
null
null
null
[null, null, null, null]
[null, null, null, null]
Eine Alternative zur Speicherung mehrdimensionaler Reihungen als Reihungen von Reihungen besteht darin, diese als eindimensionale Reihungen abzuspeichern und den Versatz einer Komponente der eindimensionalen Reihung aus den Versatzwerten einer gedachten mehrdimensionalen Reihung zu berechnen. Dies könnte Cache und Prefetcher moderner Prozessoren auch erlauben, effizienter zu arbeiten.