¿Por qué la clase Java Vector (y Stack) se considera obsoleta o en desuso?

677

¿Por qué se considera Java Vector una clase heredada, obsoleta o en desuso?

¿No es válido su uso cuando se trabaja con concurrencia?

Y si no quiero sincronizar manualmente los objetos y solo quiero usar una colección segura para subprocesos sin necesidad de hacer copias nuevas de la matriz subyacente (como lo CopyOnWriteArrayListhace), ¿está bien usarla Vector?

¿Qué pasa Stack, que es una subclase de Vector, qué debo usar en lugar de eso?

fjsj
fuente
Son obsoletos, pero no están en desuso.
Marqués de Lorne

Respuestas:

655

Vectorse sincroniza en cada operación individual. Eso casi nunca es lo que quieres hacer.

Generalmente desea sincronizar una secuencia completa de operaciones. Sincronizar operaciones individuales es menos seguro (si itera sobre Vector, por ejemplo, aún necesita quitar un bloqueo para evitar que alguien más cambie la colección al mismo tiempo, lo que provocaría un ConcurrentModificationExceptionen el hilo iterativo) pero también más lento ( ¿Por qué sacar una cerradura repetidamente cuando una vez será suficiente?

Por supuesto, también tiene la sobrecarga de bloqueo incluso cuando no es necesario.

Básicamente, es un enfoque muy defectuoso para la sincronización en la mayoría de las situaciones. Como señaló el Sr. Brian Henk , puede decorar una colección usando las llamadas tales como Collections.synchronizedList: el hecho de que Vectorcombina la implementación de la colección "matriz redimensionada" con el bit "sincronizar cada operación" es otro ejemplo de diseño deficiente; El enfoque de la decoración da una separación más limpia de las preocupaciones.

En cuanto a un Stackequivalente, miraría Deque/ ArrayDequepara comenzar.

Jon Skeet
fuente
108
"Generalmente desea sincronizar una secuencia completa de operaciones". - ¡Ese es el punto! ¡Gracias!
fjsj
77
¿en qué versión de Java Vector obsoleto (actualmente utilicé Java7), pero nunca lo veo como obsoleto? Bye the Way agradable Explicación ... + 1
Samir Mangroliya
17
@Samir: No está oficialmente en desuso, es solo que ArrayList es generalmente preferido
Jon Skeet
26
@Samir: No, no voy a tratar de predecir el futuro.
Jon Skeet
55
simplemente gr8. el vector no está en desuso, es una clase heredada. Debe haber una diferencia entre despreciado y heredado y sí, ver stackoverflow.com/questions/2873254/…
Prashant Shilimkar
82

Vector era parte de 1.0: la implementación original tenía dos inconvenientes:

1. Naming: los vectores son realmente solo listas a las que se puede acceder como matrices, por lo que deberían haberse llamado ArrayList(que es el reemplazo de las colecciones de Java 1.2 Vector).

2. Concurrencia: Todo el get(), set()métodos son synchronized, por lo que no puede haber grano fino control sobre la sincronización.

No hay mucha diferencia entre ArrayListy Vector, pero debes usarlo ArrayList.

De la API doc.

A partir de la plataforma Java 2 v1.2, esta clase se actualizó para implementar la interfaz de Lista, convirtiéndola en miembro de Java Collections Framework. A diferencia de las nuevas implementaciones de colección, Vector está sincronizado.

Justin
fuente
¿Listas a las que se puede acceder como matrices? ArrayList no es un nombre muy corto o pegadizo, lo que podría ser la razón por la que el vector se usa en otros lugares (por ejemplo, el STL).
Dhardy
66
@dhardy Lista con una matriz como su implementación subyacente. Hay ArrayList, LinkedList, etc., todos los cuales implementan la interfaz List, por lo que si desea utilizar los Listmétodos sin necesidad de saber lo que la aplicación subyacente realidad es que sólo puede tomar un Listcomo un parámetro a los métodos, etc. Lo mismo se aplica para los ejecutores de Mapy así. Mientras tanto, C ++ tiene una std::arrayclase, que es solo un reemplazo basado en plantillas para matrices de longitud estática de estilo C.
JAB
41

Además de las respuestas ya mencionadas sobre el uso de Vector, Vector también tiene un montón de métodos de enumeración y recuperación de elementos que son diferentes a la interfaz de Lista, y los desarrolladores (especialmente aquellos que aprendieron Java antes de 1.2) pueden tender a usarlos si están en el código. Aunque las enumeraciones son más rápidas, no comprueban si la colección se modificó durante la iteración, lo que puede causar problemas, y dado que Vector podría elegirse para su sincronización, con el acceso de múltiples subprocesos, esto lo convierte en un problema particularmente pernicioso. El uso de estos métodos también combina mucho código con Vector, de modo que no será fácil reemplazarlo con una implementación de Lista diferente.

Yishai
fuente
14

Puede usar el método synchronizedCollection / Listjava.util.Collection para obtener una colección segura para subprocesos de una colección no segura para subprocesos.

Brian Henk
fuente
2
¿Por qué esto es mejor que el vector?
fjsj
8
Como Jon mencionó, Vector no funcionará tan bien, y este método le permite elegir cuándo es una buena idea hacer la sincronización. Es totalmente un problema de diseño. Debería usar ArrayList sobre Vector porque debería usar de forma predeterminada el acceso no sincronizado.
Brian Henk, el
¿Cómo responde esto a la pregunta?
Marqués de Lorne
8

java.util.Stackhereda la sobrecarga de sincronización de java.util.Vector, que generalmente no está justificada.

Sin embargo, hereda mucho más que eso. El hecho de que java.util.Stack extends java.util.Vectores un error en el diseño orientado a objetos. Los puristas notarán que también ofrece muchos métodos más allá de las operaciones tradicionalmente asociadas con una pila (a saber: push, pop, peek, size). También es posible hacer search, elementAt, setElementAt, remove, y muchas otras operaciones de acceso aleatorio. Básicamente, depende del usuario abstenerse de usar las operaciones no apiladas de Stack.

Por estas razones de rendimiento y diseño de OOP, JavaDoc parajava.util.Stack recomienda ArrayDequecomo el reemplazo natural. (Una deque es más que una pila, pero al menos está restringida a manipular los dos extremos, en lugar de ofrecer acceso aleatorio a todo).

200_success
fuente