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

pourquoi Java Vector est-il considéré comme une classe legacy, obsolète ou obsolète?

est-ce que son utilisation n'est pas valide quand on travaille avec la concurrence?

et si Je ne veux pas synchroniser manuellement des objets et que je veux juste utiliser une collection sans fil sans avoir besoin de faire de nouvelles copies du tableau sous-jacent (comme CopyOnWriteArrayList le fait), alors est-il correct d'utiliser Vector ?

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

617
demandé sur Patrick Parker 2009-09-06 22:04:09

5 réponses

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

généralement, vous voulez synchroniser une séquence complète d'opérations. Synchroniser des opérations individuelles est à la fois moins sûr (si vous itérez sur un Vector , par exemple, vous avez encore besoin de sortir une serrure pour éviter que quelqu'un d'autre changer la collection en même temps, ce qui causerait un ConcurrentModificationException dans le fil itératif) mais aussi plus lent (pourquoi tirer une serrure à plusieurs reprises quand une fois sera suffisant)?

bien sûr, il a aussi la tête de verrouillage même si vous n'avez pas besoin.

fondamentalement, c'est une approche très imparfaite à la synchronisation dans la plupart des situations. Comme M. Brian Henk souligné, vous pouvez décorer une collection en utilisant les appels tels que Collections.synchronizedList - le fait que Vector combine à la fois le " tableau redimensionné" la mise en œuvre de la collection avec le bit "synchroniser chaque opération" est un autre exemple de conception médiocre; l'approche de la décoration donne une séparation plus claire des préoccupations.

Que pour un Stack équivalent - je regarderais Deque / ArrayDeque pour commencer.

607
répondu Jon Skeet 2015-09-26 12:05:27
Le Vecteur

faisait partie de 1.0 -- la mise en oeuvre initiale avait deux inconvénients:

1. Nommage: les vecteurs sont vraiment juste des listes qui peuvent être accédées en tant que tableaux, donc il aurait dû être appelé ArrayList (qui est le Java 1.2 Collections de remplacement pour Vector ).

2. Simultanéité: toutes les méthodes get() , set() sont synchronized , donc vous ne pouvez pas avoir de grain fin contrôle de la synchronisation.

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

à Partir de l'API doc.

de la plate-forme Java 2 v1.2, ce la classe a été modernisée pour mettre en œuvre la Interface de liste, ce qui en fait un membre de le cadre des Collections Java. Contrairement les nouvelles implémentations de la collection, Le vecteur est synchronisé.

75
répondu Justin 2017-09-24 07:21:24

outre les réponses déjà indiquées sur L'utilisation de Vector, Vector a également un tas de méthodes autour de l'énumération et de la récupération d'éléments qui sont différentes de l'interface de liste, et les développeurs (en particulier ceux qui ont appris Java avant 1.2) peuvent avoir tendance à les utiliser s'ils sont 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 vecteur pourrait être choisi pour sa syncronisation - avec le accès simultané à partir de plusieurs threads, ce qui en fait un problème particulièrement pernicieux. L'utilisation de ces méthodes associe également beaucoup de code à vecteur, de sorte qu'il ne sera pas facile de le remplacer par une implémentation de liste différente.

40
répondu Yishai 2009-09-06 20:53:26

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

15
répondu Brian Henk 2017-09-24 07:19:43

java.util.Stack hérite de la synchronisation aérienne de java.util.Vector , ce qui n'est généralement pas justifié.

il hérite beaucoup plus que cela, cependant. Le fait que java.util.Stack extends java.util.Vector est une erreur dans la conception orientée objet. Les puristes remarqueront qu'il offre également beaucoup de 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 nombreux autres accès aléatoire opérations. C'est essentiellement à l'utilisateur de s'abstenir d'utiliser les opérations non empilées de Stack .

pour ces raisons de performance et de conception OOP, le JavaDoc pour java.util.Stack recommande ArrayDeque comme le 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 l'accès aléatoire à tout.)

4
répondu 200_success 2016-02-12 21:04:52