748 votes

Pourquoi la classe Java Vector (et Stack) est-elle considérée comme obsolète ou dépréciée ?

Pourquoi la classe Vector de Java est-elle considérée comme une classe obsolète ou déconseillée ?

Son utilisation n'est-elle pas valide lorsqu'on travaille avec la concurrence ?

Et si je ne veux pas synchroniser manuellement les objets et que je veux simplement utiliser une collection sûre pour les threads sans avoir besoin de créer de nouvelles copies du tableau sous-jacent (comme le fait CopyOnWriteArrayList), est-il alors correct d'utiliser Vector ?

Qu'en est-il de Stack, qui est une sous-classe de Vector, que devrais-je utiliser à la place ?

1 votes

Ils sont obsolètes, mais ils ne sont pas obsolètes.

721voto

Jon Skeet Points 692016

Vector synchronise sur chaque opération individuelle. C'est presque jamais ce que vous voulez faire.

Généralement, vous voulez synchroniser une séquence entière d'opérations. Synchroniser des opérations individuelles est à la fois moins sûr (si vous itérez sur un Vector, par exemple, vous devez toujours prendre un verrou pour éviter que quelqu'un d'autre ne change la collection en même temps, ce qui provoquerait une ConcurrentModificationException dans le thread d'itération) mais aussi plus lent (pourquoi prendre un verrou à plusieurs reprises quand une fois suffit) ?

Bien sûr, cela a aussi le surcoût de verrouiller même lorsque ce n'est pas nécessaire.

Fondamentalement, c'est une approche très défectueuse de la synchronisation dans la plupart des situations. Comme l'a souligné M. Brian Henk, vous pouvez décorer une collection en utilisant des appels tels que Collections.synchronizedList - le fait que Vector combine à la fois l'implémentation de collection "tableau redimensionné" avec le bit "synchroniser chaque opération" est un autre exemple de mauvaise conception ; l'approche de la décoration donne une meilleure séparation des préoccupations.

Quant à un équivalent de Stack - je regarderais du côté de Deque/ArrayDeque pour commencer.

129 votes

"Généralement, vous voulez synchroniser une séquence complète d'opérations." - C'est le point! Merci!

7 votes

Dans quelle version de Java Deprecated Vector (actuellement j'utilise Java7). Mais je ne vois jamais comme un Déprécié? Au revoir la belle explication ... +1

20 votes

@Samir : Ce n'est pas officiellement obsolète - c'est simplement que ArrayList est généralement préféré.

92voto

Justin Points 2376

Vector faisait partie de 1.0 - l'implémentation originale avait deux inconvénients :

1. Nom: les vecteurs ne sont vraiment que des listes auxquelles on peut accéder comme des tableaux, donc cela aurait dû être appelé ArrayList(qui est le remplacement de Vector dans les Collections Java 1.2).

2. Concurrency: Toutes les méthodes get(), set() sont synchronized, donc vous ne pouvez pas avoir un contrôle fin sur la synchronisation.

Il n'y a pas beaucoup de différence entre ArrayList et Vector, mais vous devriez utiliser ArrayList.

À partir de la documentation de l'API.

A partir de la plateforme Java 2 v1.2, cette classe a été modifiée pour implémenter l'interface List, en faisant ainsi partie du Framework des Collections Java. Contrairement aux nouvelles implémentations de collections, Vector est synchronisé.

0 votes

Les listes qui peuvent être accédées comme des tableaux ? ArrayList n'est pas un nom très court ou accrocheur, c'est peut-être pour ça que vector est utilisé ailleurs (par exemple, dans la STL).

6 votes

@dhardy Liste avec un tableau comme implémentation sous-jacente. Il y a ArrayList, LinkedList, etc., tous implémentent l'interface List, donc si vous voulez utiliser les méthodes de List sans avoir à savoir quelle est l'implémentation sous-jacente, vous pouvez simplement prendre un List comme paramètre des méthodes, etc. La même chose s'applique aux implémenteurs de Map et ainsi de suite. En attendant, C++ a une classe std::array, qui est juste un remplacement basé sur des modèles pour les tableaux de longueur statique de style C.

43voto

Yishai Points 42417

En plus des réponses déjà données sur l'utilisation de Vector, Vector dispose également d'une série de méthodes autour de l'énumération et de la récupération d'éléments qui sont différentes de celles de l'interface List, et les développeurs (en particulier ceux qui ont appris Java avant la version 1.2) peuvent avoir tendance à les utiliser s'ils se trouvent dans le code. Bien que les énumérations soient plus rapides, elles ne vérifient pas si la collection a été modifiée pendant l'itération, ce qui peut causer des problèmes, et étant donné que Vector peut être choisi pour sa synchronisation - avec l'accès simultané de plusieurs threads, cela pose un problème particulièrement pernicieux. L'utilisation de ces méthodes lie également beaucoup de code à Vector, de telle sorte qu'il ne sera pas facile de le remplacer par une implémentation de List différente.

16voto

200_success Points 963

java.util.Stack hérite du surcoût de synchronisation de java.util.Vector, ce qui n'est généralement pas justifié.

Il hérite cependant de beaucoup plus que cela. Le fait que java.util.Stack étend java.util.Vector est une erreur dans la conception orientée objet. Les puristes noteront qu'il offre également de nombreuses méthodes au-delà des opérations traditionnellement associées à une pile (à savoir : push, pop, peek, size). Il est également possible de faire search, elementAt, setElementAt, remove, et de nombreuses autres opérations d'accès aléatoire. C'est essentiellement à l'utilisateur de s'abstenir d'utiliser les opérations non liées à la pile de Stack.

Pour ces raisons de performance et de conception orientée objet, le JavaDoc pour java.util.Stack recommande ArrayDeque comme remplacement naturel. (Un deque est plus qu'une pile, mais au moins il est limité à manipuler les deux extrémités, plutôt que d'offrir un accès aléatoire à tout.)

15voto

Brian Henk Points 328

Vous pouvez utiliser la méthode synchronizedCollection/List dans java.util.Collection pour obtenir une collection thread-safe à partir d'une collection non thread-safe.

4 votes

Pourquoi est-ce mieux que le vecteur?

8 votes

Comme Jon l'a mentionné, Vector ne fonctionnera pas aussi bien, et cette méthode vous permet de choisir quand c'est une bonne idée de faire la synchronisation. C'est totalement un problème de conception. Vous devriez utiliser ArrayList plutôt que Vector car vous devriez privilégier l'accès non synchronisé.

0 votes

Comment cela répond-il à la question?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X