Java ArrayListとベクター

1. 概要

このチュートリアルでは、* _ ArrayList_クラスと_Vector_クラスの違いに焦点を当てます*。 どちらもJava Collections Frameworkに属し、_java.util.List_インターフェイスを実装します。
ただし、*これらのクラスには実装に大きな違いがあります*。

2. 違いは何ですか?

クイックスタートとして、* _ ArrayList_と_Vector ._ *の主な違いを紹介しましょう。次に、いくつかのポイントについて詳しく説明します。
  • 同期-これら2つの間の最初の大きな違い。
    _Vector_は同期されますが、 ArrayList はそうではありません。

  • サイズの成長– otherもう1つの違いは、
    容量に達しながらサイズを変更します。 * _Vector_はサイズを2倍にします。 対照的に、 ArrayList はその長さの半分だけ増加します*

  • 繰り返し– And _ Vector_は_Iterator_および_Enumeration_を使用して
    要素を横断します。
    一方、_ArrayList_は_Iterator_のみを使用できます。

  • パフォーマンス–主に同期のため、_Vector_操作は
    _ArrayList_と比較すると遅い

  • フレームワーク–また、ArrayList_はコレクションフレームワークの一部です
    JDK 1.2で導入されました。 一方、「
    Vector_」は、Javaの以前のバージョンにレガシークラスとして存在します。

3. ベクター

  • _https://www.baeldung.com/java-arraylist [ArrayList、] _ ***に関する拡張ガイドが既にあるため、ここではそのAPIと機能については説明しません。 一方、_Vector_についてのコアの詳細をいくつか紹介します。

    *単にput __、__ a _Vector_はサイズ変更可能な配列です*。 要素を追加または削除すると、拡大および縮小できます。
    典型的な方法でベクターを作成できます:
Vector<String> vector = new Vector<>();
デフォルトのコンストラクターは、初期容量が10の空の_Vector_を作成します。
いくつかの値を追加しましょう:
vector.add("baeldung");
vector.add("Vector");
vector.add("example");
最後に、https://www.baeldung.com/java-iterator [_Iterator_]インターフェースを使用して、値を反復処理します。
Iterator<String> iterator = vector.iterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    // ...
}
または、_Enumeration_を使用して_Vector_を走査できます。
Enumeration e = vector.elements();
while(e.hasMoreElements()) {
    String element = e.nextElement();
    // ...
}
それでは、独自の機能のいくつかをさらに詳しく見ていきましょう。

4. 同時実行

_ArrayList_と_Vector_は同時実行戦略が異なることを既に述べましたが、詳しく見てみましょう。 _Vector's_メソッドのシグネチャに飛び込むと、それぞれにsynchronizedキーワードがあることがわかります。
public synchronized E get(int index)
簡単に言えば、*これは、一度に1つのスレッドのみが特定のベクターにアクセスできることを意味します*。
*ただし、実際には、この操作レベルの同期は、複合操作の独自の同期でオーバーレイする必要があります。*
対照的に、_ArrayList_は異なるアプローチを取ります。 そのメソッドは__not_ synchronizedであり、その懸念は並行性に専念するクラスに分けられます。
たとえば、link:/java-copy-on-write-arraylist[_CopyOnWriteArrayList_]またはlink:/java-synchronized-collections[_Collections.synchronizedList_] toを使用できます。 _Vector_と同様の効果が得られます。
vector.get(1); // synchronized
Collections.synchronizedList(arrayList).get(1); // also synchronized

5. パフォーマンス

既に上で説明したように、* _ Vector_は同期され、パフォーマンスに直接影響します*。
_Vector_ versus __ArrayList __operationsのパフォーマンスの違いを確認するために、単純なlink:/java-microbenchmark-harness[JMHベンチマーク]テストを作成してみましょう。
過去に、link:/java-collections-complexity[_ArrayList_ ’の操作の時間の複雑さ]を見てきたので、_Vector._のテストケースを追加しましょう。
_First _、_ get()_メソッドをテストしましょう:
@Benchmark
public Employee testGet(ArrayListBenchmark.MyState state) {
    return state.employeeList.get(state.employeeIndex);
}

@Benchmark
public Employee testVectorGet(ArrayListBenchmark.MyState state) {
    return state.employeeVector.get(state.employeeIndex);
}
3つのスレッドと10のウォームアップ反復を使用するようにJMHを構成します。
そして、操作あたりの平均時間をナノ秒レベルで報告しましょう。
Benchmark                         Mode  Cnt   Score   Error  Units
ArrayListBenchmark.testGet        avgt   20   9.786 ± 1.358  ns/op
ArrayListBenchmark.testVectorGet  avgt   20  37.074 ± 3.469  ns/op
  • _ArrayList#get_は、_Vector#get _。*の約3倍の速度で動作することがわかります。

    それでは、_contains()_操作の結果を比較しましょう。
@Benchmark
public boolean testContains(ArrayListBenchmark.MyState state) {
    return state.employeeList.contains(state.employee);
}

@Benchmark
public boolean testContainsVector(ArrayListBenchmark.MyState state) {
    return state.employeeVector.contains(state.employee);
}
そして結果を印刷します。
Benchmark                              Mode  Cnt  Score   Error  Units
ArrayListBenchmark.testContains        avgt   20  8.665 ± 1.159  ns/op
ArrayListBenchmark.testContainsVector  avgt   20  36.513 ± 1.266  ns/op
ご覧のとおり、_contains()_操作の場合、_Vector_のパフォーマンス時間は_ArrayList_よりもはるかに長くなります。

6. 概要

この記事では、Javaの_Vector_クラスと_ArrayList_クラスの違いを調べました。 さらに、_Vector_機能についても詳しく説明しました。
いつものように、この記事の完全なコードはhttps://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-collections [GitHub]にあります。