1。概要
このチュートリアルでは、ArrayListクラスとVectorクラスの違いに焦点を当てます。これらは両方ともJavaコレクションフレームワークに属し、java.util.Listインターフェースを実装します。
ただし、これらのクラスの実装には大きな違いがあります。
2.何が違うのですか?
クイックスタートとして、ArrayListとVectorの主な違いを紹介しましょう。次に、いくつかのポイントについて詳しく説明します。
- 同期–これら2つの最初の大きな違い。ベクトルは同期されますが、ArrayListは同期されません。
- サイズの拡大– 2つの違いは、容量に達したときにサイズを変更する方法です。ベクターは、その大きさを倍増します。対照的に、ArrayListはその長さの半分だけ増加します
- 反復–そして、VectorはIteratorとEnumerationを使用して要素をトラバースできます。一方、ArrayListはIteratorのみを使用できます。
- パフォーマンス–主に同期のため、Vector操作はArrayListと比較すると遅くなります
- フレームワーク–また、ArrayListはCollectionsフレームワークの一部であり、JDK1.2で導入されました。一方、Vectorは以前のバージョンのJavaにレガシークラスとして存在します。
3.ベクトル
ArrayListに関する拡張ガイドはすでにあるので、ここではそのAPIと機能については説明しません。一方、Vectorに関するいくつかのコアの詳細を示します。
簡単に言えば、Vectorはサイズ変更可能な配列です。要素を追加または削除すると、拡大および縮小する可能性があります。
典型的な方法でベクトルを作成できます。
Vector vector = new Vector();
デフォルトのコンストラクターは、初期容量が10の空のVectorを作成します。
いくつかの値を追加しましょう:
vector.add("baeldung"); vector.add("Vector"); vector.add("example");
最後に、Iteratorインターフェイスを使用して値を繰り返し処理してみましょう。
Iterator iterator = vector.iterator(); while (iterator.hasNext()) { String element = iterator.next(); // ... }
または、列挙型を使用してベクトルをトラバースできます。
Enumeration e = vector.elements(); while(e.hasMoreElements()) { String element = e.nextElement(); // ... }
それでは、それらの独自の機能のいくつかをさらに詳しく見ていきましょう。
4.並行性
ArrayListとVectorは同時実行戦略が異なることはすでに説明しましたが、詳しく見ていきましょう。Vectorのメソッドシグネチャに飛び込むと、それぞれに同期キーワードがあることがわかります。
public synchronized E get(int index)
簡単に言えば、これは、一度に1つのスレッドのみが特定のベクトルにアクセスできることを意味します。
ただし、実際には、この操作レベルの同期は、複合操作用の独自の同期ととにかくオーバーレイする必要があります。
したがって、対照的に、ArrayListは異なるアプローチを取ります。そのメソッドは同期されておらず、その懸念は並行性に専念するクラスに分けられます。
たとえば、CopyOnWriteArrayListまたはCollections.synchronizedListを使用して、Vectorと同様の効果を得ることができます。
vector.get(1); // synchronized Collections.synchronizedList(arrayList).get(1); // also synchronized
5.パフォーマンス
すでに上で説明したように、Vectorは同期されているため、パフォーマンスに直接影響します。
Vector操作とArrayList操作のパフォーマンスの違いを確認するために、簡単なJMHベンチマークテストを作成してみましょう。
過去に、ArrayListの操作の時間計算量を見てきましたので、Vectorのテストケースを追加しましょう。
まず、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クラスの違いについて説明しました。さらに、ベクター機能についても詳しく説明しました。
いつものように、この記事の完全なコードはGitHubで入手できます。