Vector クラスRevised: May/6th/2008; Since: Jan./1st/2002
通常の配列は、宣言時に要素になり得るデータ型とその個数を決定しなければならず、その後の変更も出来ません。クラスVectorはオブジェクトを要素とする可変長の配列を実現します。クラスVectorは、データ構造を扱う最も原始的なクラスです。
java.lang.Object
|
+--java.util.AbstractCollection
|
+--java.util.AbstractList
|
+--java.util.Vector
Vector クラスは java.util パッケージに含まれるので、利用するファイルではパッケージをインポートしておく必要があります。
API 仕様では次のように説明されています:
Vectorクラスは、オブジェクトの可変長配列を実装します。ここには配列と同じように、整数インデックスを使ってアクセスできる要素が格納されています。しかし、Vectorのサイズは、Vectorの作成後に追加および削除されたオブジェクトを格納できるように必要に応じて増やしたり減らしたりすることができます。
| コンストラクタの概要 | |
|---|---|
Vector()
空の Vector を作成し、その内部データ配列のサイズが 10 で、その標準的な増加がゼロであるようにします。 |
|
Vector(Collection<? extends E> c)
指定されたコレクションの反復子が返す順序で、その要素を格納する Vector を作成します。 |
|
Vector(int initialCapacity)
指定された初期容量、および増加量がゼロである、空の Vector を作成します。 |
|
Vector(int initialCapacity,
int capacityIncrement)
指定された容量と増加量で空の Vector を作成します。 |
|
Vector の要素の個数(サイズ)はその都度明確に決まっていますが、作成後も必要に応じて増減させることが出来ます。
メソッドの詳細な定義は API 仕様を直接ご確認ください。
要素の追加(add() 系メソッド)、挿入(insert() 系メソッド)、削除(remove() 系メソッド)、配列/文字列などへの変換、サイズ変更などのメソッドが多く定義されています。
Vector を作成し、オブジェクトを要素に追加/挿入/削除してみます。コレクションクラスが保持できる要素はオブジェクトです。プリミティブ型は保持できませんが、J2SE 5.0以上では、ボクシング変換によって、プリミティブ型でも直接add()できます。
ここでは、J2SE 5.0で追加された言語仕様ジェネリクスを用いた、型パラメータがない場合とある場合の例を挙げます。
//java.utilパケージのインポート
import java.util.*;
class TestVector {
public static void main(String[] args) {
//Vector のインスタンス化
Vector vec = new Vector();
System.out.println("----追加----");
//オブジェクトの作成
String obj1 = new String("Hello World!");
StringBuffer obj2 = new StringBuffer("こんにちは、世界!");
//要素の追加
vec.add(obj1);
vec.add(obj2);
// J2SE 1.4以下
// vec.add(Integer.valueOf("3"));
// J2SE 5.0以上
vec.add(3); // J2SE 5.0以上のみ。オートボクシング
//表示
System.out.println(vec);
System.out.println("----挿入----");
//オブジェクトの作成
// J2SE 1.4以下
// Integer obj3 = Integer.valueOf("10");
// Double obj4 = Double.valueOf("3.14");
// J2SE 5.0以上
Integer obj3 = 10; // オートボクシング
Double obj4 = 3.14; // オートボクシング
//要素の挿入
vec.insertElementAt(obj3, 1);
vec.insertElementAt(obj4, 3);
//表示
System.out.println(vec);
//要素の削除
System.out.println("----削除----");
vec.remove(2);
//表示
System.out.println(vec);
}
}
Vector の要素にするオブジェクトを作るために、String クラス、 StringBuffer クラス、ラップクラスの Integer と Double をインスタンス化しました。また、ボクシング変換の例のために、int型リテラルの3を追加しています。
D:\java>javac TestVector.java 注:TestVector.java の操作は、未チェックまたは安全ではありません。 注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください 。 D:\java>
コンパイルは完了しますが、注が出力されました。型パラメータを指定していないためです。実行は可能です(バイトコードへの影響はない)。実行結果は次のようになります。
D:\java>java TestVector ----追加---- [Hello World!, こんにちは、世界!, 3] ----挿入---- [Hello World!, 10, こんにちは、世界!, 3.14, 3] ----削除---- [Hello World!, 10, 3.14, 3] D:\java>
コンパイル時の注で指示されているオプション-Xlint:uncheckedを指定して再コンパイルすると、未検査警告メッセージが表示されます(-Xlint:allで全ての警告メッセージが出力されます。この例の場合は、未検査警告のみなので、出力結果は同じです)。
D:\java>javac -Xlint:unchecked TestVector.java
TestVector.java:15: 警告:[unchecked] raw 型 java.util.Vector のメンバとしての ad
d(E) への無検査呼び出しです。
vec.add(obj1);
^
TestVector.java:16: 警告:[unchecked] raw 型 java.util.Vector のメンバとしての ad
d(E) への無検査呼び出しです。
vec.add(obj2);
^
TestVector.java:17: 警告:[unchecked] raw 型 java.util.Vector のメンバとしての ad
d(E) への無検査呼び出しです。
vec.add(3);
^
TestVector.java:27: 警告:[unchecked] raw 型 java.util.Vector のメンバとしての in
sertElementAt(E,int) への無検査呼び出しです。
vec.insertElementAt(obj3, 1);
^
TestVector.java:28: 警告:[unchecked] raw 型 java.util.Vector のメンバとしての in
sertElementAt(E,int) への無検査呼び出しです。
vec.insertElementAt(obj4, 3);
^
警告 5 個
D:\java>
型パラメータを指定していないため、コンパイル時に、代入されたオブジェクトの型が正しいかどうかをチェックできないということが警告されています。このサンプルの場合は、複数種類の型が代入されているため、型パラメータで要素の型を特定できないので、しょうがありません。
現実的なプログラムでは、コレクションに保持するオブジェクト型は一意に決定できます。要素を取り出して操作するためには明示的なキャスト(ダウン・キャスト)が必要なので、任意の型だと自動化できないため、現実的ではありません。
J2SE 1.4までは、次のようなコードが必要でした。
import java.util.Vector;
class TestVector2 {
public static void main(String[] args) {
// 追加するオブジェクトのインスタンス化
String str1 = "Hello, World";
String str2 = "Howdy, Java!";
Integer i = Integer.valueOf("7");
// Vector型オブジェクトのインスタンス化
Vector vec = new Vector();
// オブジェクトの追加
vec.add(str1);
vec.add(str2);
vec.add(i);
for(i = 0; i < vec.size(); i++) {
// 要素の取得とキャスト
String elm = (String)vec.get(i);
System.out.println(elm);
}
}
}
この例では、要素を取得するためにforループを使っていますが、String型へキャストしています。そのため、Integer型オブジェクトが処理されるときに、ClassCastExceptionがthrowされます。
D:\java>javac TestVector2.java
注:TestVector2.java の操作は、未チェックまたは安全ではありません。
注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください
。
D:\java>javac -Xlint TestVector2.java
TestVector2.java:13: 警告:[unchecked] raw 型 java.util.Vector のメンバとしての a
dd(E) への無検査呼び出しです。
vec.add(str1);
^
TestVector2.java:14: 警告:[unchecked] raw 型 java.util.Vector のメンバとしての a
dd(E) への無検査呼び出しです。
vec.add(str2);
^
TestVector2.java:15: 警告:[unchecked] raw 型 java.util.Vector のメンバとしての a
dd(E) への無検査呼び出しです。
vec.add(i);
^
警告 3 個
D:\java>java TestVector2
Hello, World
Howdy, Java!
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer canno
t be cast to java.lang.String
at TestVector2.main(TestVector2.java:18)
D:\java>
String型のみを期待するのであれば、Integer型がadd()された時点で誤りです。このような誤りを、コンパイル時点で検査できるようにする仕組みがジェネリクスを利用した型パラメータです。
import java.util.Vector;
class TestVector3 {
public static void main(String[] args) {
// 型パラメータの指定
Vector<String> vec = new Vector<String>();
vec.add("Hello, World!");
vec.add("Howdy, Java!");
vec.add(1.60217733E-19); // コンパイルエラー
vec.add("End of the World...");
for(int i = 0; i < vec.size(); i++) {
// 明示的キャストが不要
String elm = vec.get(i);
System.out.println(elm);
}
}
}
上記のサンプルでは、型パラメータでString型を指定しています。それにも関わらず、double型である1.60217733E-19がadd()されているのでコンパイルエラーになります。コンパイル時のメッセージは次のようになります。
D:\java>javac TestVector3.java TestVector3.java:9: シンボルを見つけられません。 シンボル: メソッド add(double) 場所 : java.util.Vectorの クラス vec.add(1.60217733E-19); // コンパイルエラー ^ エラー 1 個 D:\java>
シンボルを見つけられませんというのは、メソッドadd()の引数型が、型パラメータで指定された型で定義されているからです。インスタンス化時に型パラメータが指定されていなければ、Object型が採用されてadd(Object o)を実装することになりますが、型パラメータにString型が指定された場合、そのオブジェクトはadd(String s)しか存在しなくなります。
上記のサンプルは、1.60217733E-19をダブルクオートで括って文字列にすればコンパイルを通るようになります。
D:\java>javac TestVector4.java D:\java>java TestVector4 Hello, World! Howdy, Java! 1.60217733E-19 End of the World... D:\java>
ソースコードは次の通りです。
import java.util.Vector;
class TestVector3 {
public static void main(String[] args) {
// 型パラメータの指定
Vector<String> vec = new Vector<String>();
vec.add("Hello, World!");
vec.add("Howdy, Java!");
vec.add("1.60217733E-19");
vec.add("End of the World...");
for(int i = 0; i < vec.size(); i++) {
// 明示的キャストが不要
String elm = vec.get(i);
System.out.println(elm);
}
}
}