Wie kann ich eine ArrayList mit allen Nullen in Java initialisieren?

161

Es sieht so aus, arraylistals würde es seine Aufgabe nicht erfüllen:

// presizing 

ArrayList<Integer> list = new ArrayList<Integer>(60);

Danach, wenn ich versuche, darauf zuzugreifen:

list.get(5) 

Anstatt 0 zurückzugeben, wird IndexOutOfBoundsException: Index 5 für die Länge 0 außerhalb der Grenzen ausgelöst .

Gibt es eine Möglichkeit, alle Elemente mit einer exakten Größe auf 0 zu initialisieren, wie dies in C ++ der Fall ist?

Frost
quelle
4
Das Javadoc dieses Konstruktors gibt an, dass eine "leere Liste" erstellt wird. Es macht seinen Job.
ColinD

Antworten:

429

Die an den Konstruktor übergebene Ganzzahl stellt ihre Anfangskapazität dar , dh die Anzahl der Elemente, die er halten kann, bevor die Größe seines internen Arrays geändert werden muss (und hat nichts mit der Anfangsanzahl der Elemente in der Liste zu tun).

So initialisieren Sie eine Liste mit 60 Nullen:

List<Integer> list = new ArrayList<Integer>(Collections.nCopies(60, 0));

Wenn Sie eine Liste mit 60 verschiedenen Objekten erstellen möchten , können Sie die Stream-API Supplierwie folgt verwenden:

List<Person> persons = Stream.generate(Person::new)
                             .limit(60)
                             .collect(Collectors.toList());
aioobe
quelle
1
Das ist viel besser als meine Lösung (sogar meine aktualisierte, die tatsächlich funktioniert, hehehe). Ich würde jedoch empfehlen, kein neues ArrayListdaraus zu machen und stattdessen einfach zu programmieren List. Das ist natürlich eine Entscheidung, die dem OP überlassen bleibt.
CorsiKa
6
Die von zurückgegebene Liste nCopiesist unveränderlich, daher ArrayListist es wahrscheinlich eine gute Idee , eine neue zu erstellen .
Aioobe
4
Beachten Sie, dass bei Verwendung von nCopiesmit einem komplexen Objekt die Sammlung nicht mit 60 verschiedenen Objekten instanziiert wird, sondern 60 Mal mit demselben Objekt. Verwenden Sie dies also nur für Grundelemente.
Membersound
1
@membersound, ich kann mir viele Szenarien vorstellen, in denen nCopiesReferenztypen nützlich sind: Unveränderliche Objekte wie Zeichenfolgen, Nullobjektmuster, Aufzählungskonstanten, ... Wie auch immer, ich habe die Antwort mit einer Lösung zum Erstellen von 60 verschiedenen Objekten aktualisiert.
Aioobe
@aioobe Ich weiß, dass es viele Szenarien gibt, in denen Kopien nützlich sind. Ich wollte dies nur hinzufügen, da ich Ncopies mit veränderlichen Objekten ausprobierte und überrascht war, dass es nicht wie erwartet funktionierte. Nur für den Fall, dass jemand die gleiche Aufgabe versucht. Danke für das Update!
Membersound
12
// apparently this is broken. Whoops for me!
java.util.Collections.fill(list,new Integer(0));

// this is better
Integer[] data = new Integer[60];
Arrays.fill(data,new Integer(0));
List<Integer> list = Arrays.asList(data);
corsiKa
quelle
2
Dies füllt nur eine Liste mit vorhandenen Einträgen. Es wird nicht wie gewünscht mit Elementen initialisiert.
WhiteFang34
Dies wird die Liste nicht mit 60 Nullen füllen.
Aioobe
Selbst wenn es würde, würde es 60 Objekte erstellen, bei denen es keine erstellen muss.
ColinD
1
@ Frost: Sie erhalten eine IndexOutOfBoundsExceptionmitList<Integer> list = new ArrayList<Integer>(60); Collections.fill(list, new Integer(0)); list.get(5);
WhiteFang34
1
Arrays.asListerzeugt ein List, das das Hinzufügen oder Entfernen nicht zulässt, daher ist es nicht ganz das Gleiche wie das, was das OP will. Es würde funktionieren, wenn Sie nur etwas tun müssen set, aber in diesem Fall ist es möglicherweise besser, nur ein Array zu verwenden.
ColinD
8

Die 60, die Sie übergeben, ist nur die anfängliche Kapazität für den internen Speicher. Es ist ein Hinweis darauf, wie groß Sie denken, dass es sein könnte, aber natürlich ist es nicht dadurch eingeschränkt. Wenn Sie Werte voreingestellt haben müssen, müssen Sie diese selbst festlegen, z.

for (int i = 0; i < 60; i++) {
    list.add(0);
}
WhiteFang34
quelle
4

Java 8-Implementierung (Liste mit 60Nullen initialisiert ) :

List<Integer> list = IntStream.of(new int[60])
                    .boxed()
                    .collect(Collectors.toList());
  • new int[N] - Erstellt ein Array mit Nullen und Länge N.
  • boxed() - Jedes Element ist mit einer Ganzzahl versehen
  • collect(Collectors.toList()) - sammelt Elemente des Streams
am0wa
quelle
0

So ist es nicht. ArrayList verwendet Array nur als interne Atmung. Wenn Sie mehr als 60 Elemente hinzufügen, wird das darunter liegende Array erweitert. Sie können diesem Array jedoch so viele Elemente hinzufügen, wie Sie haben.

Marcin
quelle