Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Java Quiz #28

Un petit quiz facile pour se rafraîchir en cette semaine bien chaude !
Alors, que fait ce code ?

  1. public class Summer {
  2. public static void main(String[] args) {
  3. List<String> list = new ArrayList<String>(10);
  4. Collections.fill(list, "très ");
  5. list.set(0, "Il fait ");
  6. list.set(9, "chaud !");
  7. System.out.println(list);
  8. }
  9. }

Réponse : ce code produit une exception de type IndexOutOfBoundsException.

La stacktrace nous indique que c'est la méthode set() de l'ArrayList qui pose problème, en essayant d'accéder à un élément hors des limites de la liste, en l'occurrence le premier élément de la liste (index 0). Mais nous avions pourtant utilisé le constructeur permettant de réserver 10 emplacements !

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
	at java.util.ArrayList.RangeCheck(ArrayList.java:547)
	at java.util.ArrayList.set(ArrayList.java:337)
	at test.Test.main(Test.java:11)

C'est justement là toute la subtilité des listes : la taille initiale n'est qu'une simple indication, une estimation de la taille finale de la liste fournie par le programmeur pour tenter d'éviter les dépassements de capacité et les coûteuses réallocations de mémoire associées. Concrètement, les éléments de la liste ne sont jamais pré-initialisés, et le compteur interne de la liste n'est modifié que lorsque des éléments sont réellement ajoutés ou supprimés de la collection.
C'est une différence majeure par rapport aux tableaux, dont les "cases" sont toujours initialisées à la valeur par défaut de leur type (null pour les références, 0 ou 0.0 pour les nombres, false pour les booléens).

Revenons à notre exemple.
La méthode fill() était évidemment là pour vous induire en erreur et vous laisser croire que la liste avait été initialisée. Or, il n'en est rien ; cette méthode ne remplace que les éléments existants de la liste par l'élément spécifié - autrement dit, elle ne fait rien dans notre cas.
De la même façon, la méthode set() ne permet que de remplacer un élément existant. L'élément 0 n'existant pas, une erreur est levée.

Conclusion :

  • Lisez attentivement la documentation ! Les noms des méthodes peuvent se révéler de faux amis.
  • Gardez à l'esprit les différences de comportement entre les collections et les tableaux.

Commentaires

1. Le mercredi 1 juillet 2009, 10:56 par Charles.w

Lève une IndexOutOfBoundsException. Collections.fill(list, "très") se contente de remplacer les éléments déjà stockés dans la collection par "très" comme la liste ne contient aucun élément, rien n'est remplacé. Le premier appel de list.set(0, "Il fait ") échoue car 0 n'est pas un index valide.

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.