Erstellen Sie ein Array von Arraylisten

175

Ich möchte eine Reihe von Arraylisten wie folgt erstellen:

ArrayList<Individual>[] group = new ArrayList<Individual>()[4]

Aber es wird nicht kompiliert. Wie kann ich das machen?

Benutzer
quelle
8
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?
Jimboweb

Antworten:

142

Gemäß Oracle-Dokumentation :

"Sie können keine Arrays parametrisierter Typen erstellen"

Stattdessen könnten Sie Folgendes tun:

ArrayList<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>(4);

Wie von Tom Hawting - Tackline vorgeschlagen, ist es noch besser:

List<List<Individual>> group = new ArrayList<List<Individual>>(4);
MByD
quelle
20
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>[])new ArrayList[4];
Marcus
quelle
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.
Radiodef
80

Das funktioniert:

ArrayList<String>[] group = new ArrayList[4];
Kelvinzer
quelle
1
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

class IndividualList extends ArrayList<Individual> {

}

und erstellen Sie dann das Array

IndividualList[] group = new IndividualList[10];
user2558221
quelle
17

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 n ArrayList<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?

smslce
quelle
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 = new List[number];
for (int i = 0; i < number; i++) {
    outer[i] = new ArrayList<>();
}

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 = new List[number];
Arrays.setAll(outer, element -> new ArrayList<>());

Noch besser mit Methodenreferenz

List<Integer>[] outer = new List[10];
Arrays.setAll(outer,  ArrayList :: new);
Arjun Nagathankandy
quelle
2
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.*;

public class ArrayOfArrayList {
    public static void main(String[] args) {

        // Put the length of the array you need
        ArrayList<String>[] group = new ArrayList[15];
        for (int x = 0; x < group.length; x++) {
            group[x] = new ArrayList<>();
        }

        //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 'em
        System.out.println(group[0]);
        System.out.println(group[1]);
    }
}

Dank an Kelvincer für einige Codes.

Reich
quelle
6

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

Mark Odey
quelle
Das Hinzufügen an einer bestimmten Position ist O (n) für Array und ArrayList. Das Füllen ist auch O (n) für Arrays und ArrayList.
Navin
2
Das Hinzufügen an einer bestimmten Position ist O (1) für Arrays. Es ist O (n) für ArrayList, aber O (1) für Arrays.
Aviemet
3

Sie können kein Array vom generischen Typ erstellen. Liste der ArrayLists erstellen:

 List<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>();

oder wenn Sie WIRKLICH ein Array benötigen (WARNUNG: schlechtes Design!):

 ArrayList[] group = new ArrayList[4];
Piotr Gwiazda
quelle
2
  1. Erstellung und Initialisierung

    Object[] yourArray = new Object[ARRAY_LENGTH];
  2. Schreibzugriff

    yourArray[i]= someArrayList;

    So greifen Sie auf Elemente der internen ArrayList zu:

    ((ArrayList<YourType>) yourArray[i]).add(elementOfYourType); //or other method
  3. Lesezugriff

    Um das Array-Element i als ArrayList zu lesen, verwenden Sie den Typ Casting:

    someElement= (ArrayList<YourType>) yourArray[i];

    für Array-Element i: Lesen des ArrayList-Elements am Index j

    arrayListElement= ((ArrayList<YourType>) yourArray[i]).get(j);
Amr Lotfy
quelle
2

List [] listArr = new ArrayList [4];

Die obige Zeile gibt eine Warnung aus, funktioniert aber (dh es wird ein Array von ArrayList erstellt).

Ashutosh S.
quelle
1

So deklarieren Sie ein Array von ArrayLists statisch für beispielsweise Sprite-Positionen als Punkte:

ArrayList<Point>[] positionList = new ArrayList[2];

public Main(---) {
    positionList[0] = new ArrayList<Point>(); // Important, or you will get a NullPointerException at runtime
    positionList[1] = new ArrayList<Point>();
}

dynamisch:

ArrayList<Point>[] positionList;
int numberOfLists;

public Main(---) {
    numberOfLists = 2;
    positionList = new ArrayList[numberOfLists];
    for(int i = 0; i < numberOfLists; i++) {
        positionList[i] = new ArrayList<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.

Androidcoder
quelle
1
ArrayList<String>[] lists = (ArrayList<String>[])new ArrayList[10]; 
Labeo
quelle
1

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.

Tejendra
quelle
1

ArrayList<Integer>[] graph = new ArrayList[numCourses] Es klappt.

xiankun zhu
quelle
0

Ich finde das einfacher zu bedienen ...

static ArrayList<Individual> group[];
......
void initializeGroup(int size)
{
 group=new ArrayList[size];
 for(int i=0;i<size;i++)
 {
  group[i]=new ArrayList<Individual>();
 }
Creative_Cimmons
quelle
0

Du kannst das :

// Ein Array vom Typ ArrayList erstellen

`ArrayList<Integer>[] a = new ArrayList[n];`

// Für jedes Element im Array eine ArrayList erstellen

for(int i=0; i<n; i++){ 
    a[i] = new ArrayList<Integer>();
}
Nishant Salhotra
quelle
0
ArrayList<String> al[] = new ArrayList[n+1];
for(int i = 0;i<n;i++){
   al[i] = new ArrayList<String>();
}
HeadAndTail
quelle
-1

Sie können eine Liste [] erstellen und mit der for-Schleife initialisieren. es kompiliert ohne Fehler:

List<e>[] l;
for(int i = 0; i < l.length; i++){
    l[i] = new ArrayList<e>();
}

es funktioniert auch mit arrayList [] l.

user3539906
quelle
2
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];
Erik