Vector vs ArrayList en Java

ArrayList et Vector sont les deux classes les plus utilisées dans le package collection de java et la différence entre Vector et ArrayList est une question posée très fréquemment. Bien que c'est une question simple, il est important de connaitre dans quel cas on utilise Vector ou ArrayList, particulièrement quand vous êtes entrain de travailler sur un grand projet.

Dans cet article, on va voir les points de différence entre un Vector et un ArrayList en Java et essayer de comprendre le concept derrière ces différences.

Avant d'entamer les différences entre Vector et ArrayList, voyons les similitudes entre ces deux:
  1. Vector et ArrayList utilisent une structure de stockage extensible.
  2. ArrayList et Vector utilisent une structure de tableau interne.
  3. Les deux liste maintiennent l'ordre d'insertion des éléments. Ce qui veut dire que vous pouvez récupérer l'objet dans l'ordre de son insertion si vous parcourez ArrayList ou Vector.
  4. Vector et ArrayList autorisent les éléments dupliqués et les valeurs null.
  5. Iterator et listIterator retournés par Vector et ArrayList sont de type fail-fast.

Vector vs ArrayList

1) Synchronisation
ArrayList n'est pas synchronisée, ce qui veut dire que plusieurs threads peuvent y accéder en même temps. Par exemple, si un thread est entrain de réaliser une opération d'ajout dans ArrayList, il peut arriver qu'un autre thread est entrain d'effectuer une opération de suppression en parallèle dans un environnement multi-threads non synchronisé.

Par contre Vector est synchronisé. Cela garantie un usage sécurisé des threads dans un environnement concurrent et mutli-threads. Par exemple, si un thread est entrain d'effectuer une opération dans Vector, aucun autre thread ne peut y accéder tant que le premier thread n'a pas terminé. Contrairement à ArrayList, seulement un seul thread peut effectuer une opération à la fois.

2) Performance
ArrayList est plus performante et plus rapide car elle est non synchronisée, ce qui la rend un très bon choix dans un environnement monothread. Vous pouvez aussi utiliser ArrayList dans un environnement multi-threads si les threads sont seulement entrains de lire les valeurs de ArrayList.

Etant donné que Vector est synchronisé, il paye le prix de la synchronisation ce qui le rend lent et donne de mauvaises performances. Le thread qui effectue une opération bloque l’accès aux autres threads par conséquent, ils attendent jusqu'à que le verrouillage est relâché.

3) Redimensionnement
La capacité de stockage des deux listes est extensible ou contractile, les concepteurs de java l'ont rendu dynamique pour maintenir un usage de stockage optimal. Cependant, chacune a sa méthode. ArrayList augmente par la moitié de sa taille tandis que Vector double sa taille par défaut. On peut augmenter la capacité de ArrayList en appelant la méthode ensureCapacity().

4) fail-fast
D'abord, laissons-nous comprendre ce qu'un fail-fast: si la collection (ArrayList, Vector, etc.) est modifiée à l’exception des opérations d'ajout et de suppression de iterator, après la création de iterator alors iterator va déclencher une exception ConcurrentModificationException. La modification de la structure est reliée à l'ajout ou la suppression des éléments de la collection.

Vector retourne un objet Enumeration en appelant la méthode elements() qui n'est pas fail. D'autre part, Iterator et ListIterator retournés par ArrayList sont fail-fast.

5) Qui appartient réellement au framework collection?
Vector est l'une de ces classes arrivée avec JDK 1.0 et initialement ne faisait pas partie du framework Collection mais, dans la dernière version elle a été prise en compte parce qu'elle implémente l'interface List donc, elle est devenue une partie du framework collection.

ArrayList a été introduit après Vector avec la sortie du JDK 1.2. ArrayList a été plus avancée que Vector mais elle avait aussi tous les spécifications de Vector. Donc, les gens ont commencé à utiliser ArrayList au lieu Vector, et dans ce cas, Vector est devenue une classe héritée (legacy class).

Quand utiliser Vector et ArrayList ?

Cela dépend de vos besoins, si votre code fait la synchronisation des processus (threads), Vector serait le meilleur choix puisqu'il assure qu'un seul thread accède à la collection à la fois.

Les opérations de synchronisation consomment beaucoup de temps par rapport aux opérations non-synchronisées donc, si votre application doit s'exécuter plus vite et n'a pas besoin de synchronisation, ArrayList serait le bon choix, coté performance.

Ce tableau résume les 5 différences que l'on a vu:

ArrayList Vector
1) ArrayList n'est pas synchronisé. Vector est synchronisé
2) ArrayList incrémente 50% de sa taille actuelle si le nombre des éléments dépassent sa capacité Vector invrémente 100%, cela veut dire le double de sa taille initiale si le nombre des éléments dépassent sa capacité
3) ArrayList a été introduit dans JDK 1.2. Vector a été introduit dans JDK 1.0
4) ArrayList es rapide parce qu'elle n'est pas synchronisé Vector est lent parce qu'il est synchronisé. Dans un environnement concurent, il va bloquer les autres processus à accèder jusqu'à que le premier thread autorise l'accès
5) ArrayList utilise Iterator pour parcourir les éléments Vector utilise l'interface Enumeration pour parcourir les élément mais, elle peut utiliser Iterator aussi