Comment puis-je initialiser une ArrayList avec tous les zéros en Java?

161

Il semble arraylistne pas faire son travail pour le pré-dimensionnement:

// presizing 

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

Ensuite, lorsque j'essaye d'y accéder:

list.get(5) 

Au lieu de renvoyer 0, il lève IndexOutOfBoundsException: Index 5 hors limites pour la longueur 0 .

Existe-t-il un moyen d'initialiser tous les éléments à 0 d'une taille exacte comme ce que fait C ++?

Gel
la source
4
Le Javadoc de ce constructeur spécifie qu'il crée une "liste vide". Il fait son travail.
ColinD le

Réponses:

429

L'entier passé au constructeur représente sa capacité initiale , c'est-à-dire le nombre d'éléments qu'il peut contenir avant de devoir redimensionner son tableau interne (et n'a rien à voir avec le nombre initial d'éléments dans la liste).

Pour initialiser une liste avec 60 zéros, procédez comme suit:

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

Si vous souhaitez créer une liste avec 60 objets différents , vous pouvez utiliser l'API Stream avec un Suppliercomme suit:

List<Person> persons = Stream.generate(Person::new)
                             .limit(60)
                             .collect(Collectors.toList());
aioobe
la source
1
C'est bien mieux que ma solution (même ma mise à jour qui fonctionne réellement hehehe). Je ne recommanderais pas faire une nouvelle ArrayListsur ce bien, et au lieu simplement programme List. C'est une décision laissée au PO, bien sûr.
corsiKa
6
La liste renvoyée par nCopiesest immuable, donc créer un nouveau ArrayListest probablement une bonne idée.
aioobe
4
Sachez que lorsque vous utilisez nCopiesavec un objet complexe, la collection n'est pas instanciée avec 60 objets différents, mais 60 fois avec le même objet. Alors n'utilisez ceci que pour les primitives.
publié le
1
@membersound, je peux penser à de nombreux scénarios où cela nCopiesest utile avec des types de référence: des objets immuables tels que des chaînes, des modèles d'objet nul, des constantes d'énumération, ... Quoi qu'il en soit, j'ai mis à jour la réponse avec une solution pour créer 60 objets différents.
aioobe
@aioobe Je sais qu'il existe de nombreux scénarios où ncopies est utile. Je voulais juste ajouter ceci, car j'ai essayé ncopies avec des objets mutables et j'ai été surpris que cela ne fonctionne pas comme prévu. Juste au cas où quelqu'un essaierait la même tâche. Merci pour la mise à jour!
membresound
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
la source
2
Cela ne remplit qu'une liste d'entrées existantes. Il ne l'initialisera pas avec les éléments souhaités.
WhiteFang34
Cela ne remplira pas la liste avec 60 zéros.
aioobe
Même si c'était le cas, il créerait 60 objets là où il n'en aurait pas besoin.
ColinD le
1
@Frost: vous obtiendrez un IndexOutOfBoundsExceptionavecList<Integer> list = new ArrayList<Integer>(60); Collections.fill(list, new Integer(0)); list.get(5);
WhiteFang34
2
Arrays.asListproduit un Listqui ne permet pas d'ajouter ou de supprimer, donc ce n'est pas tout à fait la même chose que ce que veut l'OP. Cela fonctionnerait si tout ce que vous avez à faire est set, mais vous feriez peut-être mieux d'utiliser simplement un tableau dans ce cas.
ColinD le
8

Le 60 que vous dépassez n'est que la capacité initiale de stockage interne. C'est un indice sur la taille que vous pensez que cela pourrait être, mais bien sûr, ce n'est pas limité par cela. Si vous avez besoin de prérégler des valeurs, vous devrez les définir vous-même, par exemple:

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

Implémentation Java 8 (Liste initialisée avec des 60zéros) :

List<Integer> list = IntStream.of(new int[60])
                    .boxed()
                    .collect(Collectors.toList());
  • new int[N] - crée un tableau rempli de zéros et de longueur N
  • boxed() - chaque élément encadré à un entier
  • collect(Collectors.toList()) - recueille des éléments de flux
am0wa
la source
0

Ce n'est pas comme ça. ArrayList utilise simplement un tableau comme respentation interne. Si vous ajoutez plus de 60 éléments, le tableau sous-jacent sera agrandi. Cependant, vous pouvez ajouter autant d'éléments à ce tableau que de RAM dont vous disposez.

Marcin
la source