Zweidimensionaler Array-Initialisierer, gefolgt von eckigen Klammern

68

Ich habe ein Problem beim Verstehen dieses Codes:

int[] it = new int[][]{{1}}[0];

Warum ist es kompilierbar und wie kann ich eine solche Erklärung verstehen?

user2654250
quelle
17
Off-Topic, aber ich bin überrascht, dass diese Frage so gut aufgenommen wird. Es scheint, dass die meisten Fragen heutzutage, die weniger als vier Sätze lang sind und / oder die Frage "Was macht das?" Sind, in Vergessenheit geraten = P.
TheGreenCabbage
6
@theGreenCabbage ausreichend interessante Fragen stehen über dem Gesetz
Richard Tingle
2
@theGreenCabbage geben Programmierern ein passendes Puzzle und sie werden sabbern. ;) (Übrigens ist diese Frage jetzt auf allen SE-Sites verfügbar)
Schatten-Assistent impft
25
Ich hoffe wirklich, dass Sie das in einem Buch mit "Java Tricks" oder so gefunden haben, und es ist kein tatsächlicher Produktionscode, den jemand geschrieben hat.
Shivan Dragon
3
Dies könnte ein vereinfachtes Beispiel für die konkrete Situation sein. Zum Beispiel könnte er ein 2x2-Feld wie dieses int[] it = new int[][]{{1, 2}, {3, 4}}[0];erstellen und die erste Zeile erhalten: Es ist nicht sehr häufig, aber es ist auch nicht der unlesbarste Code.
Jeroen Vannevel

Antworten:

103

Was Sie hier tun, ist:

  1. Deklarieren einer neuen Variablen int[] it(die ein eindimensionales Array ist)
  2. Zuweisen des Werts aus dem ersten Element [0]
  3. des zweidimensionalen Arrays new int[][]
  4. das ist initialisiert zu sein {{1}}

Sie erstellen also ein zweidimensionales Array, das Sie initialisieren, um ein Array zu enthalten, das enthält, 1und nehmen gleichzeitig das erste Element des äußeren Arrays (das ein eindimensionales Array enthält 1) und weisen es Ihrer Variablen zu.

Adam Arold
quelle
Cool. Habe heute etwas Neues gelernt. Technisch gesehen ist dieses mehrdimensionale Array also nicht erforderlich? Das {{1}}ist einfach eine einzelne 1in eine mehrdimensionale. Was könnte / würde eine solche Erklärung gebrauchen?
TheGreenCabbage
Ich sehe in diesem Zusammenhang keinen gültigen Zweck dafür. Dies kann jedoch nützlich sein, wenn Sie für einige ältere Bibliotheken Parameter in diesem Format angeben müssen.
Adam Arold
1
Sehr schöne Erklärung, "so einfach wie möglich, so komplex wie nötig" :)
Acostache
29
int[] it = new int[][]{{1}}[0];

Lassen Sie uns diese in jede Phase aufteilen und was sie bedeutet.

new int[][] 

Dies ist ein neues mehrdimensionales Array.

{{1}} 

Dies ist ein mehrdimensionales Array-Literal. Es wird ein Array erstellt, das folgendermaßen aussieht:

[0] = [1]
[1] = []
[2] = []
...
[N] = []

Beachten Sie also, dass jedes Element in diesem Array selbst ein Array ist. Dann haben Sie angegeben, dass Ihre Variable itdem ersten Array im mehrdimensionalen Array entspricht, sodass sie direkt entspricht:

int[] it = new int[] {1};
Christopher
quelle
4
Zum Zeitpunkt der Veröffentlichung habe ich keine anderen Antworten gesehen, die die Aussage so aufgeschlüsselt hätten.
Christopher
Ich mag diese Art von Erklärungen. Ich emuliere definitiv diese Art von Antwortstil, wenn ich versuche, etwas zu erklären, das einzelne Elemente aufschlüsselt, die richtig strukturiert sind. Manchmal lerne ich etwas in der Zwischenzeit, in der ich es kaputt mache! Ich benutze es auch, wenn ich versuche, meinen eigenen Code zu debuggen.
TheGreenCabbage
Schöne Aufschlüsselung, aber Sie haben den Initialisierer falsch eingegeben: {{1}}, nicht {{0}}.
Justsalt
Ich finde, der Teil " {{1}}[…] macht ein Array, das so aussieht: […][10] = [] " ist irreführend: Es gibt keine Möglichkeit, [10]weil das äußere Array nur die Größe 1 hat, also ist das einzige Element am Index 0 (und enthält ein anderes Array der Größe 1, das die Ganzzahl 1 enthält, wie Sie richtig angegeben haben). Während ich bereits bei Nitpicking bin, denke ich, dass Sie die letzte Zeile {1}nicht aktualisiert haben (sollte es nicht sein {0}). Und noch eine letzte Anmerkung, nur zum Spaß: Sie können die Zeile sogar auf nur kürzen int[] it = {1};(dies funktioniert nur, wenn Sie eine Array-Variable deklarieren, in allen anderen Fällen, die Sie benötigen new int[]{…}).
Siegi
Ich weiß es zu schätzen, dass Sie sich die Zeit genommen haben, meine Antwort zu lesen, aber nur die {1}Kritik ist gültig. Mit dem habe 0-10ich versucht zu veranschaulichen, dass der Rest leer ist .. was ich getan habe. Prost.
Christopher
9

Das new int[][]{{1}}ordnet ein neues 1x1 2D-Array zu. Das (einzige) Element wird auf 1 gesetzt.

Das [0]gibt einen Verweis auf die erste (und einzige) Zeile zurück, die vom Typ ist int[].

Das int[] it = ...deklariert eine Variable und initialisiert sie mit der obigen Referenz.

Das Endergebnis entspricht int[] it = new int[]{1}.

NPE
quelle
1
@kai: Das Ergebnis ist ein 1D-Array, aber Sie verwenden ein 2D-Array.
Jeroen Vannevel
6

Im Wesentlichen erstellen Sie ein anonymes zweidimensionales Array ( new int[][]{{1}}) und nehmen dann das erste Element dieses zweidimensionalen Arrays ( {1}) und weisen es der Variablen zu it.

Gehen wir Schritt für Schritt, denn das ist eigentlich etwas verwirrend.

new int[][]{{1}}: Dadurch wird ein zweidimensionales Array erstellt, das nur ein Element enthält: ein Array, das ein Array enthält, das eines enthält int(die Nummer 1). Da es nirgendwo einer Variablen zugewiesen ist und nach dieser Anweisung nicht mehr zugänglich ist, nennen wir es "anonym" und es hat den kleinstmöglichen Umfang.

[0]: Dies greift auf das erste Element des oben erstellten anonymen zweidimensionalen Arrays zu. Das erste Element ist ein ein - dimensionaler Array mit 1 (dh {1}).

int[] it =: Schließlich nehmen wir hier das abgerufene eindimensionale Array und speichern es in unserer Variablen.

Nebenbei bemerkt, es gibt absolut keinen Grund, dies so zu tun, und es scheint nur ein sehr interessantes Java-Puzzle zu sein.

Asteri
quelle
6

Ich werde versuchen, es zu brechen

new int[][] // an array of arrays (or 2-dimensional array)
{1} // an array instance with a single element: 1
{{1}} // an array instance with a single element: above array instance
[0] // the first element of an array

Es entspricht also in etwa dem folgenden Code:

int[] inner = new int[1]; // an empty array with length 1
inner[0] = 1;
int[][] outer = new int[1][];
outer[0] = inner;

int[] it = outer[0];
Max Fichtelmann
quelle
5
int[] it = new int[][]{{1}}[0];

Dem Integer-Array itwird Folgendes zugewiesen:

new int[][] // A new 2D array is created
{{1}} // This is an initializer. The first array in the first array gets an array of 1 item: '1'
[0] // Take the first array from the 2D array
Jeroen Vannevel
quelle