declare and initialize arrays in javadeclare and initialize arrays in java
HappyCoders Glasses

Arrays in Java initialisieren

Sven Woltmann
Sven Woltmann
Aktualisiert: 14. April 2024

In diesem Artikel lernst du verschiedenste Möglichkeiten kennen,

  • wie man in Java Arrays deklariert und initialisiert,
  • wie man sie mit Werten füllt,
  • wie man sie kopiert
  • und wie man Collections und Streams in Arrays umwandelt.

Außerdem erfährst du, was die Besonderheiten bei mehrdimensionalen Arrays in Java sind.

Arrays in Java deklarieren und initialisieren

Wir beginnen mit den wohl häufigsten Operationen, der Array-Deklaration und der Array-Initialisierung.

Arrays in Java deklarieren

Die Deklaration einer Variable ist der Zeitpunkt, zu dem wir die Variable zusammen mit ihrem Typ dem Compiler bekanntmachen. Die folgenden zwei Zeilen zeigen die Deklaration eines int-Arrays und eines String-Arrays:

int[] intArray;
String[] stringArray;Code-Sprache: Java (java)

Bei der Deklaration geben wir noch nicht die Größe des Arrays an. Die Array-Variablen (im Beispiel intArray und stringArray) enthalten nicht das Array selbst, sondern eine Referenz auf ein Array, das letztendlich ein Objekt auf dem Java-Heap ist. Erst wenn wir dieses eigentliche Array-Objekt erzeugen, müssen wir die Größe festlegen.

Bei der Array-Deklaration dürfen die eckigen Klammern auch nach dem Variablennamen stehen:

int intArray[];
String stringArray[];Code-Sprache: Java (java)

Dieser Stil wurde aus der Programmiersprache C übernommen. Alle Java-Style-Guides präferieren jedoch den zuerst gezeigten Stil, also mit den Klammern nach dem Typ und vor dem Namen.

Java-Array mit Werten initialisieren

Wir können ein Array bei der Deklaration auch gleich mit Werten initialisieren. Die folgende Code-Zeile zeigt, wie wir ein int-Array initialisieren können:

int[] winningNumbers = new int[]{14, 17, 29, 32, 45, 1, 2};Code-Sprache: Java (java)

Und so können wir z. B. ein String-Array initialisieren:

String[] fruits = new String[]{"cherry", "papaya", "huckleberry"};Code-Sprache: Java (java)

Da in den vorangegangenen zwei Beispielen der Variablentyp (int bzw. String) in der Zuweisung wiederholt wird, können wir den vorangestellten Typ auch durch var ersetzen:

var winningNumbers = new int[]{14, 17, 29, 32, 45, 1, 2};
var fruits = new String[]{"cherry", "papaya", "huckleberry"};Code-Sprache: Java (java)

Alternativ dürfen wir auch das Keword new und die zweiten Typangabe weglassen, dann muss allerdings die erste Typangabe stehen bleiben und darf nicht durch var ersetzt werden:

int[] winningNumbers = {14, 17, 29, 32, 45, 1, 2};
String[] fruits = {"cherry", "papaya", "huckleberry"};Code-Sprache: Java (java)

Auch bei der kombinierten Deklaration und Initialisierung dürfen im C-Stil die eckigen Klammern nach dem Variablennamen stehen:

int winningNumbers[] = {14, 17, 29, 32, 45, 1, 2};
String fruits[] = {"cherry", "papaya", "huckleberry"};Code-Sprache: Java (java)

Array-Deklaration und -Initialisierung separieren

Die Erzeugung eines Arrays mit Festlegung aller Array-Elemente kann auch jederzeit nach der Deklaration erfolgen.

int[] winningNumbers;
// . . .
winningNumbers = new int[]{14, 17, 29, 32, 45, 1, 2};

String[] fruits;
// . . .
fruits = new String[]{"cherry", "papaya", "huckleberry"};Code-Sprache: Java (java)

Das ist allerdings nur mit dem Keyword new möglich. Die Variante ohne new ist nur bei der im vorherigen Abschnitt gezeigten kombinierten Deklaration und Initialisierung zulässig.

Leeres Array initialisieren

Bei allen bisherigen Beispielen haben wir konkrete Werte vorgegeben, die das Array enthalten soll.

Statt ein Array mit konkreten Werten zu definieren, können wir ein Array auch zunächst nur mit der Angabe einer Größe initialisieren (s. auch Artikel Array-Länge in Java), so z. B. ein Array mit zehn int-Elementen:

int[] intArray = new int[10];Code-Sprache: Java (java)

Die Anweisung new int[10] erzeugt ein neues int-Array mit zehn Elementen. Alle Elemente werden dabei auf den Standardwert 0 gesetzt. Das Kommando hat damit denselben Effekt wie folgendes:

int[] intArray = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};Code-Sprache: Java (java)

Auch diese Art der Initialisierung könnten wir von der Deklaration trennen:

int[] intArray;
// . . .
intArray = new int[10];Code-Sprache: Java (java)

Die verschiedenen Array-Typen haben folgende Standardwerte:

  • Für die Ganzzahlen byte, short, int und long ist der Default-Wert 0.
  • Für die Gleitkommazahlen float und double ist der Default-Wert 0,0.
  • Für char ist der Default-Wert das Unicode-Zeichen "NULL" (U+0000).
  • Und für alle Objekt-Arrays ist der Default null.

Array mit Werten füllen

Nachdem wir ein Array erzeugt haben (egal auf welche der zuvor gezeigten Arten), können wir es mit Werten füllen, dazu gibt es verschiedene Möglichkeiten.

Einzelne Array-Elemente setzen

Wenn wir beispielsweise ein int-Array angelegt haben, können wir es Element für Element befüllen, z. B. mit dem Quadrat des jeweiligen Indexes:

int[] intArray = new int[11];
for (int i = 0; i < intArray.length; i++) {
  intArray[i] = i * i;
}Code-Sprache: Java (java)

Dieses Array hat dann den folgenden Inhalt:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]Code-Sprache: Klartext (plaintext)

Alle Array-Elemente auf den gleichen Wert setzen: Arrays.fill()

Über die Arrays.fill()-Methode können wir ein Array mit einheitlichen Werten füllen. Der folgende Code setzt jedes Element des Arrays auf 99:

int[] intArray = new int[10];
Arrays.fill(intArray, 99);Code-Sprache: Java (java)

Dieses Array sieht dann wie folgt aus:

[99, 99, 99, 99, 99, 99, 99, 99, 99, 99]Code-Sprache: Klartext (plaintext)

Es gibt noch eine zweite, überladene fill()-Methode mit zusätzlichen Parametern, über die man den zu füllenden Bereich festlegen kann. Der folgende Code z. B. füllt die ersten 5 Felder mit der 11 und die letzten 5 Felder mit der 77:

int[] intArray = new int[10];
Arrays.fill(intArray, 0, 5, 11);
Arrays.fill(intArray, 5, 10, 77);Code-Sprache: Java (java)

Dieses Array sieht dann wie folgt aus:

[11, 11, 11, 11, 11, 77, 77, 77, 77, 77]Code-Sprache: Klartext (plaintext)

Array mit berechneten Werten füllen: Arrays.setAll()

Im Abschnitt „Einzelne Array-Elemente setzen” habe ich dir Code gezeigt, der ein Array mittels einer Schleife mit Quadratzahlen befüllt.

Das können wir auch einfacher programmieren, und zwar mit der Methode Arrays.setAll(). Dieser Methode übergeben wir das Array sowie eine Lambda-Funktion, die den Wert eines Feldes anhand seines Indexes berechnet:

int[] intArray = new int[11];
Arrays.setAll(intArray, i -> i * i);Code-Sprache: Java (java)

Die Verwendung von setAll() macht es besonders einfach, die Verarbeitung zu parallelisieren. Wir müssen dazu lediglich setAll() durch parallelSetAll() ersetzen:

int[] intArray = new int[11];
Arrays.parallelSetAll(intArray, i -> i * i);Code-Sprache: Java (java)

Intern verwendet die Methode einen parallelen Stream und damit den gemeinsamen ForkJoinPool. Da die Berechnungsmethode statuslos ist, kann die Performance hier nahezu linear mit der Anzahl der CPU-Kerne skalieren.

Java-Array kopieren

Es gibt verschiedene Methoden in Java, um ein bestehendes Array zu kopieren.

Primitive Arrays kopieren mit clone()

Die einfachsten Art ein Array zu kopieren ist die clone()-Methode:

int[] intArray = {6, 11, 5, 7, 44, 7, 4};
int[] copy = intArray.clone();Code-Sprache: Java (java)

Dadurch entsteht ein zweites Array, das unabhängig vom ersten Array verändert werden kann. Wir können jetzt Werte in beiden Arrays ändern:

intArray[1] = 999;
copy[2] = 88;Code-Sprache: Java (java)

Das führt dazu, das beide Arrays einen unterschiedlichen Inhalt haben:

intArray: [6, 999, 5, 7, 44, 7, 4]
copy:     [6, 11, 88, 7, 44, 7, 4]Code-Sprache: Klartext (plaintext)

Grafisch kannst du dir das wie folgt vorstellen (dies ist lediglich eine symbolische Darstellung, die nur den Inhalt der Arrays wiederspiegelt – tatsächlich haben Arrays intern auch noch einen Objekt-Header und ein Feld, in dem ihre Größe gespeichert ist):

Java-Array "intArray" und das geklonte Array "copy"

Anders sieht es bei Objekt-Arrays aus...

Objekt-Arrays kopieren mit clone()

Wenn wir mit einem Objekt-Array arbeiten, müssen wir beachten, dass nur die Referenzen auf die Objekte kopiert werden, nicht die Objekte selbst.

Im folgenden Beispiel kopieren wir ein Array von StringBuilder-Objekten, ändern dann die Werte eines StringBuilder-Objekts im ersten Array und geben beide Arrays aus:

StringBuilder[] fruits = {
    new StringBuilder("cherry"),
    new StringBuilder("papaya"),
    new StringBuilder("huckleberry")
};

StringBuilder[] copy = fruits.clone();

fruits[1].reverse();

System.out.println("fruits: " + Arrays.toString(fruits));
System.out.println("copy:   " + Arrays.toString(copy));Code-Sprache: Java (java)

In der Ausgabe wirst du das umgekehrte Wort „ayapap” an der mittleren Position in beiden Arrays sehen. Das liegt daran, dass nicht das StringBuilder-Objekt kopiert wurde, sondern nur ein Pointer. D. h. beide Arrays enthalten einen Pointer auf ein- und dasselbe StringBuilder-Objekt:

Java-Array "fruits" und das geklonte Array "copy"

Wenn du ein Objekt in nur einem Array ändern möchtest, dann musst du es ersetzen, in dem du ein neues Objekt, z. B. einen neuen StringBuilder zuweist. Hängen wir einmal die folgenden Zeilen an den Code von oben an:

copy[2] = new StringBuilder("tomato");

System.out.println("fruits: " + Arrays.toString(fruits));
System.out.println("copy:   " + Arrays.toString(copy));
Code-Sprache: Java (java)

Dann wirst du folgende Ausgabe sehen – tomato befindet sich nun ausschließlich im geklonten Array:

fruits: [cherry, ayapap, huckleberry]
copy:   [cherry, ayapap, tomato]Code-Sprache: Klartext (plaintext)

Grafisch kannst du dir das wie folgt vorstellen:

Java-Array "fruits" und das geklonte und modifizierte Array "copy"

Die StringBuilder mit den Inhalten „cherry” und „ayapap” sind von beiden Arrays referenziert, der StringBuilder mit dem Inhalt „huckleberry” ist nur vom fruits-Array referenziert, und der StringBuilder mit dem Inhalt „tomato” ist nur vom copy-Array referenziert.

System.arraycopy()

Manchmal wollen wir nicht das komplette Array kopieren, sondern nur einen Teil davon. Dafür können wir die Low-Level-Methode System.arraycopy() zu Hilfe nehmen.

Nehmen wir an, wir wollen die mittleren drei Gewinnzahlen in ein anderes Array kopieren. Dann erzeugen wir zuerst ein Ziel-Array der Größe drei:

int[] winningNumbers = {14, 17, 29, 32, 45, 1, 2};
int[] middleThree = new int[3];Code-Sprache: Java (java)

Und dann rufen wir wie folgt System.arraycopy() auf und geben das Ergebnis aus:

System.arraycopy(winningNumbers, 2, middleThree, 0, 3);Code-Sprache: Java (java)

Die Methode hat die folgenden Parameter:

  1. Quell-Array
  2. Start-Position im Quell-Array
  3. Ziel-Array
  4. Start-Position im Ziel-Array
  5. Anzahl der zu kopierenden Elemente

Die folgende Grafik zeigt noch einmal die Bedeutungen der Parameter:

Java System.arraycopy()

Wir können nun das Ergebnis des Kopiervorgangs ausgeben:

System.out.println("middleThree: " + Arrays.toString(middleThree));Code-Sprache: Java (java)

Und wir sollten, passend zur Grafik oben, die folgende Ausgabe sehen:

middleThree: [29, 32, 45]Code-Sprache: Klartext (plaintext)

Arrays.copyOf()

Der Umgang mit System.arraycopy() ist etwas mühsam. Daher gibt es in der Klasse java.util.Arrays einige Hilfsmethoden, die das Kopieren erleichtern.

Mit der Methode Arrays.copyOf() können wir das komplette Array oder Teile des Arrays kopieren. Der folgende Code kopiert das vollständige Array:

int[] winningNumbers = {14, 17, 29, 32, 45, 1, 2};
int[] copy = Arrays.copyOf(winningNumbers, winningNumbers.length);
System.out.println("copy = " + Arrays.toString(copy));
Code-Sprache: Java (java)

Der zweite Parameter gibt dabei die gewünschte Länge des Ziel-Arrays an. Wenn du dir den Quellcode der Methode Arrays.copyOf() anschaust, wirst du sehen, dass diese einfach clone() aufruft, wenn der zweite Parameter der Länge des Quell-Arrays gleicht.

Wenn du als zweiten Parameter eine kürzere Länge angibst, ist die Kopie entsprechend kürzer als das Original:

int[] firstThree = Arrays.copyOf(winningNumbers, 3);
System.out.println("firstThree = " + Arrays.toString(firstThree));
Code-Sprache: Java (java)

Dieser Code gibt folgendes aus – das Ziel-Array enthält also die ersten drei Zahlen des Quell-Arrays:

firstThree = [14, 17, 29]Code-Sprache: Klartext (plaintext)

Im Quellcode von Arrays.copyOf() wirst du sehen, dass in diesem Fall zunächst ein neues Array der gewünschten Größe erzeugt wird und dann mit System.arraycopy() die gewünschten Elemente aus dem Quell-Array in das Ziel-Array kopiert werden.

Du kannst auch einen Wert angeben der größer ist als die Länge des Quell-Arrays:

int[] longerArray = Arrays.copyOf(winningNumbers, 10);
System.out.println("longerArray = " + Arrays.toString(longerArray));
Code-Sprache: Java (java)

In diesem Fall werden die restlichen Felder des Ziel-Arrays mit Default-Werten (also Nullen) aufgefüllt sein, und du erhälst folgendes Ergebnis:

longerArray = [14, 17, 29, 32, 45, 1, 2, 0, 0, 0]Code-Sprache: Klartext (plaintext)

Arrays.copyOfRange()

Um einen weiter hinten liegenden Teil aus dem Array zu kopieren, können wir Arrays.copyOfRange() verwenden. Der folgende Code kopiert die mittleren drei Elemente, so wie wir es oben mit System.arraycopy() gemacht haben:

int[] winningNumbers = {14, 17, 29, 32, 45, 1, 2};
int[] middleThree = Arrays.copyOfRange(winningNumbers, 2, 5);
System.out.println("middleThree = " + Arrays.toString(middleThree));Code-Sprache: Java (java)

Als Parameter gibst du neben dem Quell-Array die Start- und End-Position (nicht die Länge!) des zu kopierenden Bereichs an.

Wenn du in den Quellcode von copyOfRange() schaust, wirst du feststellen, dass auch diese Methode auf clone() und System.arraycopy() zurückgreift.

Arrays aus anderen Datenstrukturen erzeugen

Falls du Daten in einer Collection wie einer Liste oder einem Set hast, kannst du diese mit der toArray()-Methode in ein Array kopieren.

Liste in Array konvertieren: List.toArray()

Das folgende Beispiel zeigt vier Wege, wie du eine String-Liste in ein String-Array konvertieren kannst:

List<String> fruits = List.of("honeydew", "dragonfruit", "boysenberry");
Object[] array1 = fruits.toArray();
String[] array2 = fruits.toArray(new String[fruits.size()]);
String[] array3 = fruits.toArray(new String[0]);
String[] array4 = fruits.toArray(String[]::new);
Code-Sprache: Java (java)

Bei der ersten Variante ohne Parameter ist der Rückgabewert ein Object-Array. Das liegt daran, dass Collections wie Listen und Sets zur Laufzeit aufgrund der sogenannten Type Erasure keine Typinformationen enthalten und damit aus Sicht der JVM beliebige Objekte enthalten können.

Bei der zweiten Variante übergeben wir ein neues Array des gewünschten Typs mit der benötigten Größe. Die toArray()-Methode kopiert dann die Elemente der Liste in dieses Array.

Bei der dritten Variante übergeben wir ein neues Array des gewünschten Typs der Länge 0. Die toArray()-Methode erzeugt dann ein neues Array der benötigten Größe und kopiert die Elemente in dieses Array.

Bei der vierten Methode übergeben wir eine Referenz auf den Array-Konstruktor. Die Collection.toArray()-Methode ruft diesen Konstruktor mit dem Parameter 0 auf, erzeugt also ein Array der Länge 0 und ruft dann wiederum die dritte Methode auf.

Aleksey Shipilёv hat auf seinem Blog die Performance der verschiedenen Varianten von Collection.toArray() verglichen und ist zu dem Ergebnis gekommen, dass die erste Variante, also die, die ein Object-Array zurückliefert, die schnellste ist. Von den Varianten, die ein Array des Ziel-Typs zurückliefern, sind die Varianten drei und vier am schnellsten. Dies ist kontraintuitiv, da dabei zwei Arrays erstellt werden (erst eines der Länge 0, danach eines der erforderlichen Länge). Warum die Übergabe eines Arrays der Länge 0 trotzdem schneller ist als die Übergabe eines Arrays der passenden Größe, kannst du in dem oben verlinkten Artikel nachlesen.

Die zweite Variante kann außerdem zu einer Race Condition führen: Bei einer threadsicheren Collection, deren Größe von einem anderen Thread nach dem Aufruf von size() und vor dem Aufruf von toArray() geändert wird, würde toArray() ein Array mit der alten statt der neuen Länge zurückgeben – das Array würde also abgeschnitten oder mit Nullen aufgefüllt sein.

Ich empfehle immer die vierte Variante, also die mit dem Konstruktor-Parameter, einzusetzen, da diese in Zukunft optimiert werden könnte.

Set in Array konvertieren: Set.toArray()

Du kannst die oben gezeigten toArray()-Aufrufe unverändert verwenden, um auch ein Set in ein Array zu konvertieren:

Set<String> fruits = Set.of("honeydew", "dragonfruit", "boysenberry");
Object[] array1 = fruits.toArray();
String[] array2 = fruits.toArray(new String[fruits.size()]);
String[] array3 = fruits.toArray(new String[0]);
String[] array4 = fruits.toArray(String[]::new);
Code-Sprache: Java (java)

Wenn das Set eine definierte Iterations-Reihenfolge hat (wie z. B. ein TreeSet), dann garantieren die Set.toArray()-Methoden, dass die Elemente in Iterations-Reihenfolge in das Array kopiert werden.

Auch hier gilt meine Empfehlung, immer die vierte Variante einzusetzen.

Array aus einem Objekt-Stream erzeugen

Nicht nur Collections, sondern auch Streams haben toArray()-Methoden. Wir beginnen analog zu den Collections mit den generischen Objekt-Streams. Der folgende Code zeigt zwei Varianten, wie man einen String-Stream in ein Array umwandeln kann. Beachte, dass ein Stream nur einmal konsumiert, also auch nur einmal in ein Array umgewandelt werden darf – daher müssen wir für dieses Beispiel zwei Streams erzeugen:

Stream<String> stream1 = Stream.of("mango", "tomato", "coconut");
Object[] objects = stream1.toArray();

Stream<String> stream2 = Stream.of("cherry", "date", "raspberry");
String[] strings = stream2.toArray(String[]::new);
Code-Sprache: Java (java)

Hier gibt es nur zwei Varianten, nämlich die, die wir bei den Collections zuvor als Variante 1 und Variante 4 kennengelernt haben:

  • eine Variante ohne Typangabe, bei der nur ein Object-Array zurückgegeben werden kann,
  • und eine Variante mit einer Referenz auf den Konstruktor für den gewünschten Array-Typ.

Eine Variante, der ein Array des gewüschten Typs übergeben wird, existiert hier nicht. Dies deckt sich mit meiner Empfehlung, die Varianten 2 und 3 nicht für Collections zu verwenden. Warum gibt es diese Varianten dann bei Collections? Aus historischen Gründen: Als das Collections-Framework 1998 in Java 1.2 eingeführt wurde, gab es noch keine Methodenreferenzen, wie sie für die Übergabe des Konstruktors in Variante 4 benötigt werden.

Array aus einem primitiven Stream erzeugen

Im Gegensatz zu Collections gibt es bei Streams auch primitive Varianten, nämlich IntStream, LongStream und DoubleStream. Primitive Streams bieten nur eine einzige toArray()-Methode an. Da der Typ hier immer bekannt ist, ist eine Angabe des Typs nicht erforderlich.

Der folgende Code erstellt ein int-Array mit den Werten 1 bis 10, ein long-Array mit einer Zahlenfolge, die bei 1 beginnt und sich verdoppelt, solange der Wert unter 2.000 bleibt, und ein double-Array mit einer Zahlenfolge, die bei 1,0 beginnt und halbiert wird, bis insgesamt 8 Elemente erstellt wurden:

int[] intArray = IntStream.rangeClosed(1, 10).toArray();
long[] longArray = LongStream.iterate(1, x -> x < 2000, x -> x * 2).toArray();
double[] doubleArray = DoubleStream.iterate(1.0, x -> x / 2.0).limit(8).toArray();

System.out.println("intArray = " + Arrays.toString(intArray));
System.out.println("longArray = " + Arrays.toString(longArray));
System.out.println("doubleArray = " + Arrays.toString(doubleArray));
Code-Sprache: Java (java)

Der Code gibt folgende Arrays aus:

intArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
longArray = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
doubleArray = [1.0, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125]Code-Sprache: Klartext (plaintext)

2D Arrays in Java deklarieren und initialisieren

Mehrdimensionale Arrays in Java sind nicht wirklich mehrdimensional, sondern Arrays von Arrays. Was das genau bedeutet und wie diese Arrays deklariert und initialisiert werden, zeige ich dir in den nächsten Abschnitten am Beispiel von zweidimensionalen Arrays.

2D Array in Java deklarieren

Ein zweidimensionales Array deklarierst du wie folgt:

int[][] intMatrix;
String[][] stringMatrix;
Code-Sprache: Java (java)

Genau wie bei den eindimensionalen Arrays geben wir auch hier bei der Deklaration keine Größe an. Und auch bei mehrdimensionalen Arrays dürfen wir die Klammern im C-Stil nach dem Variablennamen schreiben:

int intMatrix[][];
String stringMatrix[][];Code-Sprache: Java (java)

Wie auch bei den eindimensionalen Arrays präferieren alle Java-Styleguides die erste Variante.

2D Array in Java initialisieren

Ein zweidimensionales Array kann direkt bei der Deklaration initialisiert werden – mit new gefolgt vom Typ und zwei Paaren aus eckigen Klammern:

int[][] intMatrix = new int[][]{{2, 3, 6}, {4, 5, 1}};Code-Sprache: Java (java)

Wenn wir new verwenden, dürfen wir am Anfang auch var schreiben:

var intMatrix = new int[][]{{2, 3, 6}, {4, 5, 1}};Code-Sprache: Java (java)

Oder wir lassen new mit der Typangabe weg – dann dürfen wir aber nicht var verwenden. Das ist die kürzeste Variante:

int[][] intMatrix = {{2, 3, 6}, {4, 5, 1}};Code-Sprache: Java (java)

Natürlich können wir auch wieder Deklaration und Initialisierung auf zwei Zeilen aufteilen, müssen dann aber in beiden Zeilen den Typ explizit angeben:

int[][] intMatrix;
intMatrix = new int[][]{{2, 3, 6}, {4, 5, 1}};
Code-Sprache: Java (java)

Wir können auch ein leeres Array erzeugen (genauer gesagt, eines, das nur Nullen enthält) und dann die Felder in einem zweiten Schritt füllen:

int[][] intMatrix = new int[2][3];
intMatrix[0][0] = 2;
intMatrix[0][1] = 3;
intMatrix[0][2] = 6;
intMatrix[1][0] = 4;
intMatrix[1][1] = 5;
intMatrix[1][2] = 1;Code-Sprache: Java (java)

Wichtig zu wissen ist, dass in Java ein zweidimensionales Array eigentlich ein Array von Arrays ist. Die Beispiel-Arrays, die wir in diesem Abschnitt erzeugt haben, werden im Speicher wie folgt abgelegt (die Darstellung verzichtet wieder auf den Objekt-Header und das Längenfeld):

Java 2D array - representation in memory

Jede Zeile der Matrix ist ein separates Array. Du kannst auf diese Arrays auch zugreifen, sie z. B. wie folgt ausgeben:

int[] row0 = intMatrix[0];
int[] row1 = intMatrix[1];
System.out.println("row0 = " + Arrays.toString(row0));
System.out.println("row1 = " + Arrays.toString(row1));
Code-Sprache: Java (java)

Wir könnten das intMatrix-Array auch wie folgt erzeugen:

int[][] intMatrix = new int[2][3];
intMatrix[0] = new int[]{2, 3, 6};
intMatrix[1] = new int[]{4, 5, 1};
Code-Sprache: Java (java)

Die Unter-Arrays intMatrix[0] und intMatrix[1] werden dabei in der ersten Zeile initial jeweils auf {0, 0, 0} gesetzt und dann in der zweiten und dritten Zeile durch neue Arrays überschrieben.

Wir können die Größenangabe für die zweite Dimension in der ersten Zeile auch weglassen:

int[][] intMatrix = new int[2][]; // ⟵ without second dimension length
intMatrix[0] = new int[]{2, 3, 6};
intMatrix[1] = new int[]{4, 5, 1};
Code-Sprache: Java (java)

In diesem Fall sind intMatrix[0] und intMatrix[1] initial jeweils null.

Es ist übrigens nicht vorgeschrieben, dass alle Unter-Arrays gleich lang sein müssen. Auch folgendes ist erlaubt:

int[][] intMatrix = new int[2][];
intMatrix[0] = new int[]{2, 3, 6};
intMatrix[1] = new int[]{4, 5, 1, 9, 7};Code-Sprache: Java (java)

Und auch das dürften wir schreiben:

int[][] intMatrix = {{2, 3, 6}, {4, 5, 1, 9, 7}};Code-Sprache: Java (java)

Die in den letzten zwei Beispielen erzeugten 2D-Arrays können wir uns grafisch wie folgt vorstellen:

Java 2D array with different row lengths - representation in memory

Die in den vorherigen Abschnitten behandelten Methoden Arrays.fill(), Arrays.setAll(), clone(), System.arraycopy(), Arrays.copyOf(), Arrays.copyOfRange() lassen sich auf beiden Ebenen solch eines verschachtelten Arrays anwenden.

Der folgende Code z. B. erzeugt eine Matrix mit den Produkten des kleinen Einmaleins:

int[][] products = new int[11][11];
for (int i = 0; i < 11; i++) {
  int finalI = i; // ⟵ we need an effectively final variable for the lambda
  Arrays.setAll(products[i], j -> finalI * j);
}Code-Sprache: Java (java)

Der folgende Code setzt alle Zeilen einer zweidimensionalen Matrix auf ein Array mit den Werten eins bis vier:

int[][] matrix = new int[3][];
Arrays.fill(matrix, new int[]{1, 2, 3, 4});Code-Sprache: Java (java)

Beachte allerdings, dass wir dieses innere Array nur einmal erzeugt haben und dass alle Zeilen auf dasselbe innere Array verweisen:

Java 2D Array mit geteiltem inneren Array

Wenn du den folgenden Code ausführst, wirst du sehen, dass die vermeintliche Änderung eines einzigen Feldes der Matrix eine ganze Spalte verändert hat:

matrix[1][1] = 99;
System.out.println("matrix = " + Arrays.deepToString(matrix));Code-Sprache: Java (java)

Um für jede Zeile ein separates Array zu erzeugen, kannst du Arrays.setAll() verwenden, da hier das im zweiten Parameter übergebene Lambda für jede Zeile aufgerufen wird:

Arrays.setAll(matrix, ignored -> new int[]{1, 2, 3, 4});Code-Sprache: Java (java)

Es ist gut, diese Besonderheiten von mehrdimensionalen Arrays in Java zu kennen.

Fazit

In diesem Artikel hast du verschiedenste Methoden kennengelernt, um in Java Arrays zu erzeugen – von der Initialisierung mit statischen Werten oder Default-Werten über das Befüllen eines Arrays mit Arrays.fill() oder Arrays.setAll() und das Kopieren von Arrays mit clone(), System.arrayCopy() und Arrays.copyOf() bis hin zur Umwandlung aus bestehenden Datenstrukturen wie Listen, Sets und Streams.

Du kennst nun außerdem die Besonderheiten mehrdimensionaler Arrays in Java und weißt, worauf du bei deren Verwendung achten musst.

Wenn dir der Artikel gefallen hat, teile den Artikel über einen der Share-Buttons am Ende oder hinterlasse mir einen Kommentar.

Möchtest du informiert werden, wenn neue Artikel auf HappyCoders.eu veröffentlicht werden? Dann klicke hier, um dich für den HappyCoders.eu-Newsletter anzumelden.