Por que a classe Java Vector (e Stack) é considerada obsoleta ou obsoleta?

677

Por que o Java Vector é considerado uma classe herdada, obsoleta ou obsoleta?

Seu uso não é válido ao trabalhar com simultaneidade?

E se eu não quiser sincronizar objetos manualmente e apenas desejar usar uma coleção segura para threads sem precisar fazer novas cópias da matriz subjacente (como CopyOnWriteArrayListfaz), então é bom usar Vector?

Que tal Stack, que é uma subclasse Vector, o que devo usar em vez disso?

fjsj
fonte
Eles são obsoletos, mas não são preteridos.
Marquês de Lorne #

Respostas:

655

Vectorsincroniza em cada operação individual. Isso quase nunca é o que você quer fazer.

Geralmente você deseja sincronizar toda uma sequência de operações. A sincronização de operações individuais é menos segura (se você iterar sobre uma Vector, por exemplo, ainda precisará bloquear um bloqueio para evitar que outras pessoas alterem a coleção ao mesmo tempo, o que causaria um ConcurrentModificationExceptionno encadeamento de iteração), mas também mais lento ( por que fechar repetidamente uma fechadura quando uma vez será suficiente)?

Obviamente, ele também tem a sobrecarga de travamento, mesmo quando você não precisa.

Basicamente, é uma abordagem muito falha para sincronização na maioria das situações. Como o Sr. Brian Henk apontou, você pode decorar uma coleção usando as chamadas como Collections.synchronizedList- o fato de Vectorcombinar a implementação da coleção "array redimensionada" com o bit "sincronizar todas as operações" é outro exemplo de design inadequado; a abordagem de decoração oferece uma separação mais limpa das preocupações.

Quanto a um Stackequivalente - eu iria olhar para Deque/ ArrayDequepara começar.

Jon Skeet
fonte
108
"Geralmente você deseja sincronizar toda uma sequência de operações." - Esse é o ponto! Obrigado!
fjsj 7/09/09
7
em qual versão do vetor obsoleto java (atualmente eu usei o Java7) .Mas eu nunca vejo como obsoleto? Tchau, o bom caminho Explicação ... + 1
Samir Mangroliya
17
@ Samir: Não é oficialmente reprovado - é apenas que geralmente ArrayList é o preferido.
Jon Skeet
26
@ Samir: Não, não vou tentar prever o futuro.
Jon Skeet
5
simplesmente gr8. vetor não é obsoleto é um legado class.There deve ser diferença entre obsoleto e legado e sim, há ver stackoverflow.com/questions/2873254/...
Prashant Shilimkar
82

O vetor fazia parte do 1.0 - a implementação original tinha duas desvantagens:

1. Nomeação: os vetores são realmente apenas listas que podem ser acessadas como matrizes, portanto deveriam ter sido chamadas ArrayList(que é a substituição do Java 1.2 Collections Vector).

2. Concorrência: Toda a get(), set()métodos são synchronized, então você não pode ter grão fino controle sobre sincronização.

Não há muita diferença entre ArrayList e Vector, mas você deve usar ArrayList.

No documento da API.

A partir da plataforma Java 2 v1.2, essa classe foi adaptada para implementar a interface List, tornando-a membro do Java Collections Framework. Diferentemente das novas implementações de coleção, o Vector é sincronizado.

Justin
fonte
Listas que podem ser acessadas como matrizes? ArrayList não é um nome muito curto ou atraente, e pode ser por isso que o vetor é usado em outros lugares (por exemplo, o STL).
Dhardy 6/13
6
@dhardy Lista com uma matriz como sua implementação subjacente. Há ArrayList, LinkedListetc., todos os quais implementar a interface List, por isso, se você quiser utilizar os Listmétodos sem ter que saber o que a implementação subjacente na verdade é que você pode apenas tomar um Listcomo um parâmetro para métodos, etc. O mesmo se aplica para os implementadores de Mape assim por diante. Enquanto isso, o C ++ possui uma std::arrayclasse, que é apenas uma substituição baseada em modelo para matrizes de comprimento estático no estilo C.
JAB
41

Além das respostas já declaradas sobre o uso do Vector, o Vector também possui vários métodos de enumeração e recuperação de elementos diferentes da interface da Lista, e os desenvolvedores (especialmente aqueles que aprenderam Java antes da 1.2) podem tender a usá-los se estiverem no diretório código. Embora as enumerações sejam mais rápidas, elas não verificam se a coleção foi modificada durante a iteração, o que pode causar problemas, e como o Vector pode ser escolhido para sua sincronização - com o acesso do atendente de vários encadeamentos, isso o torna um problema particularmente pernicioso. O uso desses métodos também associa muito código ao Vector, de forma que não será fácil substituí-lo por uma implementação de Lista diferente.

Yishai
fonte
14

Você pode usar o método synchronizedCollection / Listjava.util.Collection para obter uma coleção segura para threads de uma coleção não segura para threads.

Brian Henk
fonte
2
por que isso é melhor que vetor?
fjsj 6/09/09
8
Como Jon mencionou, o vetor não terá um bom desempenho e esse método permite que você escolha quando é uma boa ideia fazer a sincronização. É totalmente uma questão de design. Você deve usar ArrayList sobre Vector, porque você deve usar como padrão o acesso não sincronizado.
Brian Henk
Como isso responde à pergunta?
Marquês de Lorne #
8

java.util.Stack herda a sobrecarga de sincronização de java.util.Vector , que geralmente não é justificada.

Herda muito mais do que isso, no entanto. O fato de java.util.Stack extends java.util.Vectorhaver um erro no design orientado a objetos. Os puristas observam que ele também oferece muitos métodos além das operações tradicionalmente associadas a uma pilha (a saber: push, pop, peek, size). Também é possível fazer search, elementAt, setElementAt, remove, e muitas outras operações de acesso aleatório. Basicamente, cabe ao usuário abster-se de usar as operações sem pilha deStack .

Por esses motivos de desempenho e design de POO, o JavaDoc forjava.util.Stack recomendado ArrayDequecomo substituto natural. (Um deque é mais do que uma pilha, mas pelo menos está restrito a manipular as duas extremidades, em vez de oferecer acesso aleatório a tudo.)

200_success
fonte