2012-01-04 6 views
6

Pourquoi java.lang.IndexOutOfBoundsException est généré dans cet exemple si la taille de ArrayList a été prédéfinie? Comment résoudre ce problème?Index ArrayList hors limites

int size = 2: 
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size); 
Integer[] value1 = {1,2,3}; 
Integer[] value2 = {1,2}; 
nums.add(1,value1); // java.lang.IndexOutOfBoundsException 
nums.add(0,value2); 

Répondre

11

Vous ne pouvez pas mettre un élément dans une ArrayList avant que l'autre soit défini. Si vous voulez le faire, vous devez d'abord attribuer des valeurs nulles à l'objet sur l'emplacement 0.

Il fonctionnera si vous faites:

int size = 2: 
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size); 
Integer[] value1 = {1,2,3}; 
Integer[] value2 = {1,2}; 
nums.add(0, null); 
nums.add(1,value1); 
nums.set(0,value2); 

modifier/ajouter Remplacée par là pour remplacer l'objet null

+3

Pour être plus clair, il est vraiment que vous ne pouvez pas insérer un élément à un indice qui n'existe pas encore. –

+3

Pour ne pas deviner la sagesse ici, mais le 3e ajout() dans la solution ci-dessus * déplace * le contenu, de sorte que valeur1 est maintenant à l'index 2, pas 1? Le doc sur add() avec un index l'indique. Je crois que le contenu du tableau après ceci serait {value2, null, value1}. – rfeak

2

Au moment où vous add() à la ArrayList, la longueur de la liste est 0 Vous ne pouvez pas ajouter passé la fin actuelle du List.

Je vous conseille de faire:

nums.add(value2); 
nums.add(value1); 

Pour obtenir l'ordre que vous semblez vouloir ici.

+0

Cela ne marchera pas pour mon cas, car je pourrais avoir besoin d'ajouter un certain élément à la position 5, le suivant à la position 2, le suivant à la position 7, etc. –

+1

@KlausosKlausos - On dirait que vous ne voulez pas vraiment une ArrayList, au moins pas initialement. Il peut être préférable de commencer avec un tableau simple de certaine taille, de faire toutes vos insertions par index afin de ne pas avoir à jouer à des jeux amusants avec ArrayList, puis de mettre le tableau dans une ArrayList. Sachez également que add() à un index provoque un décalage dans le contenu existant du tableau. Ajoutant à la position 5, puis la position 2 change ce que vous avez inséré à 5 pour être maintenant à 6. – rfeak

8

L'argument au constructeur ArrayList n'est pas la taille de la liste, comme votre code suppose; c'est la capacité du stockage sous-jacent utilisé par la structure de données.

La capacité augmente au fur et à mesure que vous ajoutez des éléments à la liste. La seule raison de spécifier la capacité initiale dans le constructeur est de pré-allouer une plus grande capacité si vous savez que vous allez ajouter beaucoup d'éléments. Cela signifie que le tableau sous-jacent ne doit pas être redimensionné trop souvent lorsque vous l'ajoutez.

Quelle que soit la valeur que vous spécifiez dans le constructeur ArrayList, la taille de la liste est régie uniquement par ce que vous mettez, vous ne pouvez pas chercher l'élément avec index de 1 jusqu'à ce que vous avez ajouté à au moins 2 éléments.

0

Pour obtenir le résultat que vous voulez avoir, vous devez écrire

nums.add(0, value1); 
nums.add(0, value2); 
2

http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(int)

Ce que vous spécifiez c'est la capacité initiale, c'est juste la taille initiale que le tableau interne a et est augmenté automatiquement si besoin est. Il n'a rien à voir avec la position de l'article, d'où votre erreur. À propos, la capacité par défaut pour ArrayLists est 10, donc vous le faites en fait plus petit que le défaut.

1

Selon le javadoc, Lorsque vous écrivez

ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size); 

Vous n'êtes pas définir la taille de nums, vous définissez la capacité initiale - en ce sens, ArrayLists « aren t comme des tableaux intégrés (valeur1 et valeur2 dans votre code).

Vous pouvez essayer vous-même: imprimer la taille de nums après chaque ligne (code nettoyé pour empêcher la IndexOutOfBoundsException

int size = 2: 
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size); 
Integer[] value1 = {1,2,3}; 
Integer[] value2 = {1,2}; 
System.out.println(nums.size()); 
nums.add(value2); 
System.out.println(nums.size()); 
nums.add(value1); 
System.out.println(nums.size()); 

Ce imprimera.

0 
1 
2 
0

Pour obtenir les résultats que vous attendez, je recommanderais d'utiliser des tableaux typés de base comme

Integer[][] nums = new Integer[size][]; 

puis

Integer[] value1 = {1,2,3}; 
Integer[] value2 = {1,2}; 
nums[1] = value1; 
nums[0] = value2; 

Si vous avez besoin d'un ArrayList il suffit d'utiliser

new ArrayList<Integer[]>(Arrays.asList(nums));