Java Vector(およびStack)クラスが廃止または廃止されたと見なされるのはなぜですか?


677

Java Vectorが旧式のクラス、廃止された、または廃止されたのはなぜですか?

同時実行で使用する場合、その使用は有効ではありませんか?

また、オブジェクトを手動で同期したくない場合で、基になる配列の新しいコピーを作成する必要なくスレッドセーフなコレクションを使用したい場合は、使用しても問題ありCopyOnWriteArrayListませVectorんか?

StackサブクラスであるについてVectorはどうですか?それの代わりに何を使用すればよいですか?


廃止されましたが、非推奨ではありません。
ローンの侯爵

回答:


655

Vector個々の操作ごとに同期します。それはあなたがしたいことはほとんど決してありません。

通常は、一連の操作全体を同期させます。個々の操作の同期は安全性が低くなります(Vectorたとえば、を反復する場合でも、他のユーザーが同時にコレクションを変更するのを防ぐためにロックを解除する必要があります。これによりConcurrentModificationException、反復スレッドでが発生します)が遅くなります(一度だけで十分なときに、なぜロックを繰り返し解除するのですか?

もちろん、必要がない場合でもロックのオーバーヘッドがあります。

基本的に、これはほとんどの状況での同期に対する非常に欠陥のあるアプローチです。以下のようミスターブライアンヘンクは指摘し、あなたが電話を使用してコレクションを飾ることができるようなCollections.synchronizedList-という事実Vectorコンバイン両方の「すべての操作を同期」ビットと「サイズ変更された配列」コレクションの実装は貧弱な設計の別の例です。装飾アプローチは、問題をより明確に分離します。

Stack同等-私は見たいDeque/ ArrayDequeで開始します。


108
「一般的には、一連の操作全体を同期させたい」- そこが肝心だ!ありがとう!
fjsj 2009

7
どのバージョンのjava Deprecated Vector(現在、私はJava7を使用していたか)ですが、Deprecatedとは表示されませんか?さようなら素敵な説明... +1
サミールマングロリア

17
@Samir:正式には非推奨ではありません-単にArrayListが一般的に好まれているだけです。
Jon Skeet

26
@サミール:いいえ、私は未来を予測しようとするつもりはありません。
Jon Skeet

5
単にgr8。vectorは非推奨ではなく、レガシークラスです。非推奨とレガシーには違いがあるはずです。そうです、stackoverflow.com
questions / 2873254 /…を

82

Vectorは1.0の一部でした。元の実装には2つの欠点がありました。

1.ネーミング:ベクトルは実際には配列としてアクセスできる単なるリストなので、呼び出される必要がありますArrayList(これはのJava 1.2コレクションの置き換えですVector)。

2.同時実行性:すべてのget()set()メソッドはsynchronized同期を細かく制御することはできません。

そこの間に大きな違いはないArrayListとはVector、しかし、あなたは使用する必要がありますArrayList

APIドキュメントから。

Java 2プラットフォームv1.2以降、このクラスはListインターフェースを実装するために改良され、Java Collections Frameworkのメンバーになりました。新しいコレクションの実装とは異なり、Vectorは同期されます。


配列としてアクセスできるリスト?ArrayListは非常に短い名前やキャッチーな名前ではありません。そのため、ベクターが他の場所(STLなど)で使用されているのかもしれません。
dhardy 2013年

6
基になる実装として配列を含む@dhardyリスト。ありますArrayListLinkedListインターフェイスを実装するすべては、など、Listあなたが利用したいのであれば、List基本となる実装が実際にあなただけ取ることができているかを知ることなく、方法をListなど、メソッドのパラメータと同じでの実装に適用されますMap等々。一方、C ++にはstd::arrayクラスがあり、これはCスタイルの静的長さ配列のテンプレートベースの置き換えにすぎません。
JAB 2014年

41

Vectorの使用に関する既述の回答に加えて、VectorにはListインターフェースとは異なる列挙および要素の取得に関するメソッドの束もあり、開発者(特に1.2より前にJavaを学んだ人)は、それらがコード。列挙型の方が高速ですが、反復中にコレクションが変更されたかどうかをチェックしないため、問題が発生する可能性があります。また、同期のためにベクターが選択されている可能性があるため、複数のスレッドからのアテンダントアクセスで、これは特に悪質な問題になります。これらのメソッドを使用すると、多くのコードがVectorに結合されるため、別のList実装に簡単に置き換えることはできません。


14

synchronizedCollection / Listメソッドを使用してjava.util.Collection、非スレッドセーフコレクションからスレッドセーフコレクションを取得できます。


2
なぜこれがベクトルより優れているのですか?
fjsj 2009

8
Jonが述べたように、Vectorは同様に機能せず、この方法を使用すると、同期を行うのに適した時期を選択できます。完全に設計上の問題です。デフォルトでは非同期アクセスに設定する必要があるため、VectorではArrayListを使用する必要があります。
Brian Henk

これはどのように質問に答えますか?
ローンの侯爵

8

java.util.Stack の同期オーバーヘッドを継承します java.util.Vector、通常は正当化されません。

それはそれよりもはるかに多くを継承します。これjava.util.Stack extends java.util.Vectorがオブジェクト指向設計の誤りです。純粋主義者は、スタックに従来から関連付けられていた操作(つまり、プッシュ、ポップ、ピーク、サイズ)以外にも多くのメソッドを提供していることに気付くでしょう。それは何をすることも可能ですsearchelementAtsetElementAtremove、および他の多くのランダム・アクセス・オペレーション。の非スタック操作の使用を控えるのは、基本的にユーザー次第ですStack

これらの性能とOOPの設計上の理由から、のJavaDocをjava.util.Stack推奨していますArrayDequeは自然な代替としてしています。(両端キューはスタック以上のものですが、少なくともすべてにランダムアクセスを提供するのではなく、両端を操作することに制限されています。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.