Mischen Sie keine Arrays und Sammlungen. Verwenden Sie keine Arrays, es sei denn, Sie haben es mit Grundelementen zu tun (oder Sie wissen, was Sie tun). Arrays sind ein Alptraum für die Benutzerfreundlichkeit. Sie machen Ihren Code nicht mehr wartbar.
Sean Patrick Floyd
13
@ SeanPatrickFloyd Können Sie erklären, warum Arrays ein Alptraum für die Benutzerfreundlichkeit sind?
Benutzer
3
@crucifiedsoul sicher. Ein Array kann nicht wachsen, Sie können nichts in ein Array einfügen, ein Array überschreibt keine Standardmethoden wie gleich Hashcode oder toString usw.
Sean Patrick Floyd
9
@SeanPatrickFloyd okay - nun, ich brauche genau vier Arraylisten - ich plane, auf jeden per Index zuzugreifen - ich brauche das äußere Array nicht, um zu wachsen oder zu schrumpfen - ich brauche keinen toString oder Hashcode usw. - - Für mich ist hier ein Array die naheliegende Wahl - was würden Sie in dieser Situation als Alternative empfehlen?
BrainSlugs83
4
Okay, das ist eine alte Frage, aber ich werde sie trotzdem stellen und sehen, ob jemand antwortet. Ich sehe alle darüber reden, warum eine Reihe von Listen eine schreckliche Idee, eine schlechte Codierungspraxis usw. ist. Ich habe dies nachgeschlagen, weil ich lerne, Hash-Ketten zu erstellen, und die Definition einer Hash-Kette ist eine Reihe von Listen! Wie genau kann eine zentrale Programmierdatenstruktur eine schreckliche Codierungspraxis sein? Oder fällt dies einfach in die von @Sean erwähnte IYKWYD-Kategorie?
List<List<Individual>> group = new ArrayList<List<Individual>>();wäre wahrscheinlich besser.
Tom Hawtin - Tackline
4
Was bedeutet "kann kein Array vom generischen Typ erstellen"? Das macht für mich keinen Sinn, weil es kein Generikum ist, wenn Sie angeben, was es halten soll, oder?
Andy
5
Ich bin überrascht von den positiven Stimmen, da sie die Frage nicht beantworten (dh ich möchte dies tun, wie kann ich es tun). Außer vielleicht für den 1. Satz.
Florian F
15
Warum ist die Listenreferenz besser als ArrayList?
Shifu
3
@shifu Eine Listenreferenz ist allgemeiner als ArrayList. Wenn Sie als Liste deklarieren, wird die API von ArrayList abstrahiert, die über die Listen-API hinausgeht. Das ist gut so, weil es den Verweis auf List vereinfacht, dessen API wahrscheinlich die Gesamtheit dessen enthält, wofür die Liste sowieso benötigt wird, ohne die API dieser Referenz mit den Extras zu überladen, die ArrayList hat. Sie sollten nur dann als ArrayList deklarieren, wenn Sie etwas Bestimmtes aus der API benötigen, um über die Referenz verfügbar zu sein.
Cellepo
98
Wie die anderen bereits erwähnt haben, ist es wahrscheinlich besser, eine andere Liste zum Speichern der ArrayList zu verwenden, aber wenn Sie ein Array verwenden müssen:
ArrayList<Individual>[] group =(ArrayList<Individual>[])newArrayList[4];
Niemand scheint gut zu erklären, warum und ich mag dein Snippet oben. Warum empfehlen Sie die Verwendung einer Liste darüber?
Clankill3r
3
Wenn sich die Array- Gruppe nicht ändert, ist dieser Ansatz besser, da Arrays schneller sind als List <> -Klassen.
Borzh
33
Vielen Dank, dass Sie die Frage tatsächlich beantwortet haben. Es gibt keinen logischen Grund, automatisch anzunehmen, dass eine Liste einem Array ohne weiteren Kontext vorzuziehen ist.
Spezielle Soße
3
Gibt es einen Grund, warum dies @kelvincer Answer ( ArrayList<String>[] group = new ArrayList[4]) vorzuziehen ist ? Was tun die Darsteller besonders gut?
Cellepo
2
Sie sollten verwenden new ArrayList<?>[N], um die Verwendung eines Rohtyps zu vermeiden.
Dies hat zufriedenstellend den gewünschten Vorteil, dass das Hinzufügen einer ArrayList eines beliebigen Objekts außer String (dh: ArrayList<String>anstelle von ArrayList<NotString>) groupnicht kompiliert wird
cellepo
12
Dies erzeugt eine Warnung:Note: hello.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
Mathe
24
Sie können eine Klasse erstellen, die ArrayList erweitert
Ich verstehe es überhaupt nicht, warum jeder speziell für diese Frage den Genric-Typ über dem Array vorschlägt.
Was ist, wenn ich nverschiedene Arraylisten indizieren muss ?
Wenn List<List<Integer>>ich deklariere, dass ich nArrayList<Integer>Objekte manuell erstellen oder eine for-Schleife einfügen muss, um nListen oder auf andere Weise zu erstellen , ist es immer meine Pflicht, nListen zu erstellen .
Ist es nicht toll, wenn wir es durch Casting als deklarieren? List<Integer>[] = (List<Integer>[]) new List<?>[somenumber] . Ich sehe es als ein gutes Design, bei dem man nicht alle Indizierungsobjekte (Arraylisten) selbst erstellen muss
Kann mich jemand aufklären, warum dies (Arrayform) ein schlechtes Design sein wird und was seine Nachteile sind?
AFAICT es scheint eine Art Frachtkultmentalität zu sein, die durch das schreckliche Schreibsystem hervorgerufen wird, das Java auf den Tisch bringt.
BrainSlugs83
@smsIce: Es ist kein schlechtes Design. Das Problem ist, dass viele Autoren die vollständige Frage nicht lesen oder klar verstehen.
Testo
16
Sie können ein Array von ArrayList erstellen
List<Integer>[] outer =newList[number];for(int i =0; i < number; i++){
outer[i]=newArrayList<>();}
Dies ist in solchen Szenarien hilfreich. Sie kennen die Größe des äußeren. Aber die Größe der inneren variiert. Hier können Sie ein Array mit fester Länge erstellen, das größenvariable Array-Listen enthält. Hoffe das wird hilfreich für dich sein.
In Java 8 und höher können Sie dies viel besser tun.
List<Integer>[] outer =newList[number];Arrays.setAll(outer, element ->newArrayList<>());
Wenn Sie das verwenden ArrayList::new, wird der ArrayList(int)Konstruktor mit dem aktuellen Index als Argument aufgerufen - ArrayList (1), ArrayList (2), ArrayList (3) usw. Sie erhalten also entweder unter- oder übergroße Arrays. abhängig von Ihrer Nutzung. Ich würde davon abraten und stattdessen den zweiten Ansatz bevorzugen, bei dem Sie den Konstruktor selbst in Ihrem Lambda-Ausdruck aufrufen.
Genhis
8
Dies funktioniert, Array von ArrayList. Versuchen Sie es zu verstehen, wie es funktioniert.
import java.util.*;publicclassArrayOfArrayList{publicstaticvoid main(String[] args){// Put the length of the array you needArrayList<String>[] group =newArrayList[15];for(int x =0; x < group.length; x++){
group[x]=newArrayList<>();}//Add some thing to first array
group[0].add("Some");
group[0].add("Code");//Add some thing to Secondarray
group[1].add("In here");//Try to output 'emSystem.out.println(group[0]);System.out.println(group[1]);}}
Das Problem in dieser Situation besteht darin, dass Sie bei Verwendung einer Arrayliste eine Zeitkomplexität von o (n) für das Hinzufügen an einer bestimmten Position erhalten. Wenn Sie ein Array verwenden, erstellen Sie einen Speicherort, indem Sie Ihr Array deklarieren. Daher ist es konstant
So deklarieren Sie ein Array von ArrayLists statisch für beispielsweise Sprite-Positionen als Punkte:
ArrayList<Point>[] positionList =newArrayList[2];publicMain(---){
positionList[0]=newArrayList<Point>();// Important, or you will get a NullPointerException at runtime
positionList[1]=newArrayList<Point>();}
dynamisch:
ArrayList<Point>[] positionList;int numberOfLists;publicMain(---){
numberOfLists =2;
positionList =newArrayList[numberOfLists];for(int i =0; i < numberOfLists; i++){
positionList[i]=newArrayList<Point>();}}
Trotz der Vorsichtsmaßnahmen und einiger komplexer Vorschläge habe ich festgestellt, dass ein Array von ArrayLists eine elegante Lösung für die Darstellung verwandter ArrayLists desselben Typs darstellt.
l.lengthist in der for-Schleife undefiniert. Dies kann ein Laufzeitfehler sein.
Bourbaki4481472
l wird nicht mit einer Länge initialisiert, es ist immer noch ein Nullzeiger, wenn es die for-Schleife erreicht. dh Liste <e> [] l = neue Liste [LÄNGE];
Antworten:
Gemäß Oracle-Dokumentation :
Stattdessen könnten Sie Folgendes tun:
Wie von Tom Hawting - Tackline vorgeschlagen, ist es noch besser:
quelle
List<List<Individual>> group = new ArrayList<List<Individual>>();
wäre wahrscheinlich besser.Wie die anderen bereits erwähnt haben, ist es wahrscheinlich besser, eine andere Liste zum Speichern der ArrayList zu verwenden, aber wenn Sie ein Array verwenden müssen:
quelle
ArrayList<String>[] group = new ArrayList[4]
) vorzuziehen ist ? Was tun die Darsteller besonders gut?new ArrayList<?>[N]
, um die Verwendung eines Rohtyps zu vermeiden.Das funktioniert:
quelle
ArrayList<String>
anstelle vonArrayList<NotString>
)group
nicht kompiliert wirdNote: hello.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
Sie können eine Klasse erstellen, die ArrayList erweitert
und erstellen Sie dann das Array
quelle
Ich verstehe es überhaupt nicht, warum jeder speziell für diese Frage den Genric-Typ über dem Array vorschlägt.
Was ist, wenn ich
n
verschiedene Arraylisten indizieren muss ?Wenn
List<List<Integer>>
ich deklariere, dass ichn
ArrayList<Integer>
Objekte manuell erstellen oder eine for-Schleife einfügen muss, umn
Listen oder auf andere Weise zu erstellen , ist es immer meine Pflicht,n
Listen zu erstellen .Ist es nicht toll, wenn wir es durch Casting als deklarieren?
List<Integer>[] = (List<Integer>[]) new List<?>[somenumber]
. Ich sehe es als ein gutes Design, bei dem man nicht alle Indizierungsobjekte (Arraylisten) selbst erstellen mussKann mich jemand aufklären, warum dies (Arrayform) ein schlechtes Design sein wird und was seine Nachteile sind?
quelle
Sie können ein Array von ArrayList erstellen
Dies ist in solchen Szenarien hilfreich. Sie kennen die Größe des äußeren. Aber die Größe der inneren variiert. Hier können Sie ein Array mit fester Länge erstellen, das größenvariable Array-Listen enthält. Hoffe das wird hilfreich für dich sein.
In Java 8 und höher können Sie dies viel besser tun.
Noch besser mit Methodenreferenz
quelle
ArrayList::new
, wird derArrayList(int)
Konstruktor mit dem aktuellen Index als Argument aufgerufen - ArrayList (1), ArrayList (2), ArrayList (3) usw. Sie erhalten also entweder unter- oder übergroße Arrays. abhängig von Ihrer Nutzung. Ich würde davon abraten und stattdessen den zweiten Ansatz bevorzugen, bei dem Sie den Konstruktor selbst in Ihrem Lambda-Ausdruck aufrufen.Dies funktioniert, Array von ArrayList. Versuchen Sie es zu verstehen, wie es funktioniert.
Dank an Kelvincer für einige Codes.
quelle
Das Problem in dieser Situation besteht darin, dass Sie bei Verwendung einer Arrayliste eine Zeitkomplexität von o (n) für das Hinzufügen an einer bestimmten Position erhalten. Wenn Sie ein Array verwenden, erstellen Sie einen Speicherort, indem Sie Ihr Array deklarieren. Daher ist es konstant
quelle
Sie können kein Array vom generischen Typ erstellen. Liste der ArrayLists erstellen:
oder wenn Sie WIRKLICH ein Array benötigen (WARNUNG: schlechtes Design!):
quelle
Erstellung und Initialisierung
Schreibzugriff
So greifen Sie auf Elemente der internen ArrayList zu:
Lesezugriff
Um das Array-Element i als ArrayList zu lesen, verwenden Sie den Typ Casting:
für Array-Element i: Lesen des ArrayList-Elements am Index j
quelle
List [] listArr = new ArrayList [4];
Die obige Zeile gibt eine Warnung aus, funktioniert aber (dh es wird ein Array von ArrayList erstellt).
quelle
So deklarieren Sie ein Array von ArrayLists statisch für beispielsweise Sprite-Positionen als Punkte:
dynamisch:
Trotz der Vorsichtsmaßnahmen und einiger komplexer Vorschläge habe ich festgestellt, dass ein Array von ArrayLists eine elegante Lösung für die Darstellung verwandter ArrayLists desselben Typs darstellt.
quelle
quelle
Sie können so erstellen
ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];
Sie müssen ein Array vom nicht generischen Typ erstellen und es dann in ein generisches umwandeln.
quelle
ArrayList<Integer>[] graph = new ArrayList[numCourses]
Es klappt.quelle
Ich finde das einfacher zu bedienen ...
quelle
Du kannst das :
// Ein Array vom Typ ArrayList erstellen
// Für jedes Element im Array eine ArrayList erstellen
quelle
quelle
Sie können eine Liste [] erstellen und mit der for-Schleife initialisieren. es kompiliert ohne Fehler:
es funktioniert auch mit arrayList [] l.
quelle
l.length
ist in der for-Schleife undefiniert. Dies kann ein Laufzeitfehler sein.