Java Language Arrays erstellen und initialisieren

Beispiel

Grundlegende Fälle

int[]   numbers1 = new int[3];                 // Array for 3 int values, default value is 0
int[]   numbers2 = { 1, 2, 3 };                // Array literal of 3 int values
int[]   numbers3 = new int[] { 1, 2, 3 };      // Array of 3 int values initialized
int[][] numbers4 = { { 1, 2 }, { 3, 4, 5 } };  // Jagged array literal
int[][] numbers5 = new int[5][];               // Jagged array, one dimension 5 long
int[][] numbers6 = new int[5][4];              // Multidimensional array: 5x4

Arrays können mit einem beliebigen Grundelement oder Referenztyp erstellt werden.

float[]  boats = new float[5];          // Array of five 32-bit floating point numbers.
double[] header = new double[] { 4.56, 332.267, 7.0, 0.3367, 10.0 };
                                       // Array of five 64-bit floating point numbers.
String[] theory = new String[] { "a", "b", "c" };
                                       // Array of three strings (reference type).
Object[] dArt = new Object[] { new Object(), "We love Stack Overflow.", new Integer(3) };
                                       // Array of three Objects (reference type).

Beachten Sie für das letzte Beispiel, dass Untertypen des deklarierten Array-Typs im Array zulässig sind.

Arrays für benutzerdefinierte Typen können auch ähnlich zu primitiven Typen erstellt werden

UserDefinedClass[] udType = new UserDefinedClass[5];

Arrays, Sammlungen und Streams

Java SE 1.2
// Parameters require objects, not primitives

// Auto-boxing happening for int 127 here
Integer[]       initial        = { 127, Integer.valueOf( 42 ) };
List<Integer>   toList         = Arrays.asList( initial );  // Fixed size! 

// Note: Works with all collections
Integer[]       fromCollection = toList.toArray( new Integer[toList.size()] );

//Java doesn't allow you to create an array of a parameterized type
List<String>[]  list = new ArrayList<String>[2];  // Compilation error!
Java SE 8
// Streams - JDK 8+
Stream<Integer> toStream       = Arrays.stream( initial );
Integer[]       fromStream     = toStream.toArray( Integer[]::new );

Intro

Ein Array ist eine Datenstruktur, die eine feste Anzahl von Grundwerten oder Referenzen auf Objektinstanzen enthält.

Jedes Element in einem Array wird als Element bezeichnet, und auf jedes Element wird über seinen numerischen Index zugegriffen. Die Länge eines Arrays wird festgelegt, wenn das Array erstellt wird:

int size = 42;
int[] array = new int[size];

Die Größe eines Arrays wird bei der Initialisierung zur Laufzeit festgelegt. Sie kann nach der Initialisierung nicht geändert werden. Wenn die Größe zur Laufzeit veränderbar sein muss, sollte stattdessen eine Collection Klasse wie ArrayList verwendet werden. ArrayList speichert Elemente in einem Array und unterstützt die Größenänderung, indem ein neues Array zugewiesen und Elemente aus dem alten Array kopiert werden.

Wenn das Array von einem primitiven Typ ist, d

int[] array1 = { 1,2,3 };
int[] array2 = new int[10];

Die Werte werden im Array selbst gespeichert. In Abwesenheit eines Initialisierers (wie in array2 oben) ist der jedem Element zugewiesene Standardwert 0 (Null).

Wenn der Array-Typ eine Objektreferenz ist, wie in

SomeClassOrInterface[] array = new SomeClassOrInterface[10];

dann enthält das Array Verweise auf Objekte vom Typ SomeClassOrInterface . Diese Verweise können sich auf eine Instanz von SomeClassOrInterface oder eine beliebige Unterklasse (für Klassen) oder die implementierende Klasse (für Schnittstellen) von SomeClassOrInterface . Wenn die Array-Deklaration keinen Initialisierer hat, wird jedem Element der Standardwert null zugewiesen.

Da alle Arrays int -indexiert sind, muss die Größe eines Arrays durch ein int angegeben werden. Die Größe des Arrays kann nicht als long :

long size = 23L;
int[] array = new int[size]; // Compile-time error:
                             // incompatible types: possible lossy conversion from
                             // long to int

Arrays verwenden ein auf Null basierendes Indexsystem , das heißt, die Indizierung beginnt bei 0 und endet bei length - 1 0 .

Das folgende Bild stellt beispielsweise ein Array mit der Größe 10 . Hier befindet sich das erste Element am Index 0 und das letzte Element am Index 9 , anstelle des ersten Elements am Index 1 und des letzten Elements am Index 10 (siehe Abbildung unten).

Ein Array von 10 Elementen

Zugriffe auf Elemente von Arrays erfolgen in konstanter Zeit . Das bedeutet, dass der Zugriff auf das erste Element des Arrays (zeitlich) die gleichen Kosten für den Zugriff auf das zweite Element, das dritte Element usw. verursacht.

Java bietet verschiedene Möglichkeiten zum Definieren und Initialisieren von Arrays, einschließlich Literal- und Konstruktornotationen . Bei der Deklaration von Arrays mit dem new Type[length] -Konstruktor wird jedes Element mit den folgenden Standardwerten initialisiert:

Erstellen und Initialisieren von primitiven Arrays

int[] array1 = new int[] { 1, 2, 3 }; // Create an array with new operator and 
                                      // array initializer.
int[] array2 = { 1, 2, 3 };           // Shortcut syntax with array initializer.
int[] array3 = new int[3];            // Equivalent to { 0, 0, 0 }
int[] array4 = null;                  // The array itself is an object, so it
                                      // can be set as null.

Bei der Deklaration eines Arrays erscheint [] als Teil des Typs am Anfang der Deklaration (nach dem Typnamen) oder als Teil des Deklarators für eine bestimmte Variable (nach Variablenname) oder beides:

int array5[];       /* equivalent to */  int[] array5;
int a, b[], c[][];  /* equivalent to */  int a; int[] b; int[][] c;
int[] a, b[];       /* equivalent to */  int[] a; int[][] b;
int a, []b, c[][];  /* Compilation Error, because [] is not part of the type at beginning
                       of the declaration, rather it is before 'b'. */    
// The same rules apply when declaring a method that returns an array:
int foo()[] { ... } /* equivalent to */  int[] foo() { ... }

Im folgenden Beispiel sind beide Deklarationen korrekt und können ohne Probleme kompiliert und ausgeführt werden. Sowohl die Java Coding Convention als auch der Google Java Style Guide raten jedoch davon ab, dass das Formular mit Klammern hinter dem Variablennamen steht. Die Klammern geben den Array-Typ an und sollten mit der Typbezeichnung angezeigt werden . Dasselbe sollte für Methodenrücksignaturen verwendet werden.

float array[]; /* and */ int foo()[] { ... } /* are discouraged */
float[] array; /* and */ int[] foo() { ... } /* are encouraged */

Der entmutigte Typ ist für übergebende C-Benutzer gedacht , die mit der Syntax für C vertraut sind, das nach dem Variablennamen die Klammern hat.

In Java können Arrays der Größe 0 :

int[] array = new int[0]; // Compiles and runs fine.
int[] array2 = {};        // Equivalent syntax.

Da es sich jedoch um ein leeres Array handelt, können keine Elemente daraus gelesen oder zugewiesen werden:

array[0] = 1;     // Throws java.lang.ArrayIndexOutOfBoundsException.
int i = array2[0]; // Also throws ArrayIndexOutOfBoundsException.

Solche leeren Arrays sind normalerweise als Rückgabewerte nützlich, so dass sich der aufrufende Code nur um den Umgang mit einem Array kümmern muss, anstatt einen potenziellen null , der zu einer NullPointerException führen NullPointerException .

Die Länge eines Arrays muss eine nicht negative ganze Zahl sein:

int[] array = new int[-1]; // Throws java.lang.NegativeArraySizeException

Die Arraygröße kann mithilfe eines öffentlichen letzten Felds namens length :

System.out.println(array.length); // Prints 0 in this case.

Anmerkung : array.length gibt die tatsächliche Größe des Arrays und nicht die Anzahl der array.length zurück, denen ein Wert zugewiesen wurde, im Gegensatz zu ArrayList.size() das die Anzahl der array.length zurückgibt, denen ein Wert zugewiesen wurde.

Erstellen und Initialisieren von mehrdimensionalen Arrays

Die einfachste Methode zum Erstellen eines mehrdimensionalen Arrays ist wie folgt:

int[][] a = new int[2][3];

Es werden zwei int Arrays mit drei Längen erstellt - a[0] und a[1] . Dies ist der klassischen Initialisierung im C-Stil von rechteckigen mehrdimensionalen Arrays sehr ähnlich.

Sie können gleichzeitig erstellen und initialisieren:

int[][] a = { {1, 2}, {3, 4}, {5, 6} };

Im Gegensatz zu C müssen , wenn nur rechteckige mehrdimensionale Arrays unterstützt werden, innere Arrays nicht die gleiche Länge haben oder sogar definiert sein:

int[][] a = { {1}, {2, 3}, null };

Hier ist a[0] ein int Array mit einer Länge, wohingegen a[1] ein int Array mit zwei Längen und a[2] null . Arrays wie dieses werden gezackte Arrays oder unregelmäßige Arrays genannt , das heißt Arrays von Arrays. Mehrdimensionale Arrays in Java werden als Arrays von Arrays implementiert, dh array[i][j][k] entspricht ((array[i])[j])[k] . Im Gegensatz zu C # wird das Syntax- array[i,j] in Java nicht unterstützt.

Mehrdimensionale Array-Darstellung in Java

Visuelle Darstellung eines mehrdimensionalen Java-Arrays

Source - Live auf Ideone

Erstellen und Initialisieren von Referenztyp- Arrays

String[] array6 = new String[] { "Laurel", "Hardy" }; // Create an array with new 
                                                      // operator and array initializer.
String[] array7 = { "Laurel", "Hardy" };              // Shortcut syntax with array 
                                                      // initializer.
String[] array8 = new String[3];                      // { null, null, null }
String[] array9 = null;                               // null

Live auf Ideone

Zusätzlich zu den oben gezeigten String Literalen und Primitiven funktioniert die Abkürzungssyntax für die Array-Initialisierung auch mit kanonischen Object :

Object[] array10 = { new Object(), new Object() };

Da Arrays kovariant sind, kann ein Referenztyparray als Array einer Unterklasse ArrayStoreException werden. Eine ArrayStoreException wird jedoch ausgelöst, wenn Sie versuchen, ein Element auf einen anderen String als einen String :

Object[] array11 = new String[] { "foo", "bar", "baz" };
array11[1] = "qux"; // fine
array11[1] = new StringBuilder(); // throws ArrayStoreException

Die Shortcut-Syntax kann dafür nicht verwendet werden, da die Shortcut-Syntax einen impliziten Typ von Object[] .

Ein Array kann mit null Elementen unter Verwendung von String[] emptyArray = new String[0] initialisiert werden. Ein Array mit der Länge Null wie diesem wird beispielsweise zum Erstellen eines Array aus einer Collection wenn die Methode den Laufzeittyp eines Objekts benötigt.

Sowohl bei primitiven als auch bei Referenztypen initialisiert eine leere Array-Initialisierung (z. B. String[] array8 = new String[3] ) das Array mit dem Standardwert für jeden Datentyp .

Generische Typ- Arrays erstellen und initialisieren

In generischen Klassen können Arrays generischer Typen aufgrund von Typlöschung nicht wie folgt initialisiert werden:

public class MyGenericClass<T> {
    private T[] a;

    public MyGenericClass() {
        a = new T[5]; // Compile time error: generic array creation
    }
}

Sie können stattdessen mit einer der folgenden Methoden erstellt werden: (Beachten Sie, dass diese ungeprüfte Warnungen erzeugen.)

  1. Erstellen Sie ein Object Array und geben Sie es in einen generischen Typ um:

    a = (T[]) new Object[5];
    

    Dies ist die einfachste Methode. Da das zugrunde liegende Array jedoch immer noch vom Typ Object[] bietet diese Methode keine Typsicherheit. Daher wird diese Methode zum Erstellen eines Arrays am besten nur innerhalb der generischen Klasse verwendet - nicht öffentlich verfügbar gemacht.

  2. Verwenden Sie Array.newInstance mit einem Klassenparameter:

    public MyGenericClass(Class<T> clazz) {
        a = (T[]) Array.newInstance(clazz, 5);
    }
    

    Hier muss die Klasse von T explizit an den Konstruktor übergeben werden. Der Rückgabetyp von Array.newInstance ist immer Object . Diese Methode ist jedoch sicherer, da das neu erstellte Array immer vom Typ T[] ist und daher sicher externalisiert werden kann.

Array nach der Initialisierung füllen

Java SE 1.2

Arrays.fill() kann verwendet werden, um ein Array nach der Initialisierung mit demselben Wert zu füllen:

Arrays.fill(array8, "abc");        // { "abc", "abc", "abc" }

Live auf Ideone

fill() kann auch jedem Element des angegebenen Bereichs des Arrays einen Wert zuweisen:

Arrays.fill(array8, 1, 2, "aaa");  // Placing "aaa" from index 1 to 2.

Live auf Ideone

Java SE 8

Seit Java Version 8 können mit der Methode setAll und ihrem Concurrent Äquivalent parallelSetAll jedes Element eines Arrays auf generierte Werte gesetzt werden. Diesen Methoden wird eine Generatorfunktion übergeben, die einen Index akzeptiert und den gewünschten Wert für diese Position zurückgibt.

Im folgenden Beispiel wird ein Integer-Array erstellt und alle Elemente auf ihren jeweiligen Indexwert festgelegt:

int[] array = new int[5];
Arrays.setAll(array, i -> i); // The array becomes { 0, 1, 2, 3, 4 }.

Live auf Ideone

Separate Deklaration und Initialisierung von Arrays

Der Wert eines Index für ein Array-Element muss eine ganze Zahl (0, 1, 2, 3, 4, ...) und weniger als die Länge des Arrays sein (Indizes basieren auf Null). Andernfalls wird eine ArrayIndexOutOfBoundsException ausgelöst:

int[] array9;             // Array declaration - uninitialized
array9 = new int[3];      // Initialize array  - { 0, 0, 0 }
array9[0] = 10;           // Set index 0 value - { 10, 0, 0 }
array9[1] = 20;           // Set index 1 value - { 10, 20, 0 }
array9[2] = 30;           // Set index 2 value - { 10, 20, 30 }

Arrays können mit der Array-Initialisierungs-Verknüpfungssyntax nicht erneut initialisiert werden

Es ist nicht möglich, ein Array über eine Verknüpfungssyntax mit einem Array-Initialisierer erneut zu initialisieren, da ein Array-Initialisierer nur in einer Felddeklaration oder einer Deklaration lokaler Variablen oder als Teil eines Ausdrucks zur Array-Erstellung angegeben werden kann.

Es ist jedoch möglich, ein neues Array zu erstellen und es der Variablen zuzuweisen, die zum Referenzieren des alten Arrays verwendet wird. Während dies dazu führt, dass das Array, auf das diese Variable verweist, neu initialisiert wird, ist der Inhalt der Variablen ein völlig neues Array. Zu diesem Zweck kann der new Operator mit einem Array-Initialisierer verwendet und der Array-Variablen zugewiesen werden:

// First initialization of array
int[] array = new int[] { 1, 2, 3 };

// Prints "1 2 3 ".
for (int i : array) {
    System.out.print(i + " ");
}

// Re-initializes array to a new int[] array.
array = new int[] { 4, 5, 6 };

// Prints "4 5 6 ".
for (int i : array) {
    System.out.print(i + " ");
}

array = { 1, 2, 3, 4 }; // Compile-time error! Can't re-initialize an array via shortcut 
                        // syntax with array initializer.

Live auf Ideone