web-dev-qa-db-ja.com

Java Vector(およびStack)クラスが廃止予定または推奨されなくなったのはなぜですか。

なぜJava Vectorはレガシークラスと見なされているのですか。

並行処理を使用している場合、その使用は有効ではありませんか?

手動でオブジェクトを同期させたくなくて、(CopyOnWriteArrayListがそうであるように)基礎となる配列の新しいコピーを作らずにスレッドセーフなコレクションを使いたいだけなら、Vectorを使うのはいいのですか?

StackのサブクラスであるVectorはどうなりますか?代わりに何を使うべきですか?

642
fjsj

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

一般に、操作のシーケンス全体を同期します。個々の操作の同期は安全性が低くなります(たとえば、Vectorを反復処理する場合は、ロックを解除して、コレクションを同時に変更するユーザーを回避する必要があります。これにより、反復スレッドでConcurrentModificationExceptionが発生します)遅い(なぜ十分なときにロックを繰り返し解除するのか)

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

基本的に、ほとんどの状況での同期に対する非常に欠陥のあるアプローチです。 ミスター・ブライアン・ヘンクが指摘したように、 Collections.synchronizedList などの呼び出しを使用してコレクションを飾ることができます-Vectorが両方を組み合わせるという事実「すべての操作を同期する」ビットを使用した「サイズ変更された配列」コレクションの実装は、設計が不十分な別の例です。デコレーションアプローチにより、懸念事項をより明確に分離できます。

同等のStackについては、Deque/ArrayDequeを見てみましょう。

634
Jon Skeet

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

1.命名: ベクトルは実際には配列としてアクセスできる単なるリストなので、ArrayListと呼ばれるべきです(これはVectorの代わりとなるJava 1.2コレクションです)。

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

ArrayListVectorの間に大きな違いはありませんが、ArrayListを使うべきです。

APIドキュメントより.

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

78
Justin

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

41
Yishai

スレッドセーフでないコレクションからスレッドセーフなコレクションを取得するには、Java.util.CollectionsynchronizedCollection/List メソッドを使用します。

14
Brian Henk

Java.util.StackJava.util.Vectorの同期オーバーヘッドを継承していますが、これは通常正当化されません。

ただし、それはそれ以上のものを継承しています。 Java.util.Stack extends Java.util.Vectorがオブジェクト指向設計の誤りです。純粋主義者は、それが伝統的にスタックに関連した操作(すなわち、プッシュ、ポップ、ピーク、サイズ)を超えた多くの方法も提供することに気付くでしょう。 searchelementAtsetElementAtremove、および他の多くのランダムアクセス操作を実行することもできます。 Stackの非スタック操作の使用を控えるのは基本的にユーザー次第です。

これらのパフォーマンスとOOP設計上の理由から、 JavaDoc for Java.util.Stack は自然な置き換えとして ArrayDeque を推奨します。 (dequeはスタック以上のものですが、少なくともすべてへのランダムアクセスを提供するのではなく、両端を操作することに制限されています。)

6
200_success