Java: 動的配列 ArrayList と Vector の違い とサンプルコード


Java には 動的配列 ArrayListVector があります。 (それに加えて LinkedList というのもあります。) いずれも Collection インターフェース、 List インターフェース を実装しており、 使い方はほとんど同じです。 歴史的には Vector のほうが ArrayList よりも先に作られました。

この記事では、 それら2つのクラスの違いと、それを検証するサンプルコードを紹介します。

環境

このページのコードは、 下記の環境でコンパイル・実行しています。

  • OpenJDK 11

ArrayList と Vector の違い

ArrayList はマルチスレッドで複数のスレッドからアクセスされると、正しく動作しないことがあります。 一方で Vector はスレッドセーフです。

ArrayListsynchronizedList メソッド を施すと、 スレッドセーフになります。

検証コード

ArrayListVector の違いをコードで確かめてみます。

ArrayList, Vector に、 1,024 の要素を追加してすべて取り除くというプログラムで、 追加された要素が正しく取り除かれるのか検証します。 ArrayList については synchronizedList を施したものとそうでないものと、両方検証します。

比較対象

  • Vector
  • ArrayList
  • synchronizedList を施した ArrayList

ArrayList, VectorList インターフェース を通して扱います。 test メソッド を実行すると、検証できるようにしています。 具体的には次のコードを順次実行します。

要素を追加するコード

for (int i = 0; i < SIZE; ++i) list.add(i);List に要素を追加します。 この部分で 1,024 の要素を追加します。

まだマルチスレッドにしていませんから、 確実に 1.024 の要素を追加できます。

要素を取り除くスレッドを実行するコード

次の部分のコードでスレッドを生成・実行します。

各スレッドは最初のひとつの要素を取り除くようになっています。 そのスレッドを 1,024 個 起動して、 全ての要素を取り除きます。

スレッドの内容は次のようになっています。

途中で Thread.sleep を実行しているのは、 このようにして要素を取り除く順番が乱れるようにしておかないと、スレッドを使っていないのと同じ結果になってしまうからです。

結果を出力するコード

System.out.println(title + ": " + list.size()); で最後に残された要素数を出力しています。

結果

結果は次のように出力されました。 ArrayList をそのまま使った場合のみ、 全ての要素が取り除かれていませんね。