javax.vecmath.Vector2dクラスの挙動
Javaで幾何学を扱うときには、javax.vecmath パッケージのお世話になる。
javax.vecmath パッケージには、ベクトルを扱うために便利な Vector2d クラスや Vector3d クラスが含まれる。
このベクトルクラスについて、見事にはまったことがあったので、以下は備忘目的で。
Vector2d クラスおよび Vector3d クラスは、通常のオブジェクト指向の感覚で使用すると痛い目にあう。
むしろ、Vector2d や Vector3d は、Stringクラスまたは、Double や Integer クラスと同じようなものだと考えた方がいい。
たとえば、ArrayList や Vector、HashMapなどのコレクションに格納して、contains メソッドを使う時、オブジェクトの比較ではなく、値の比較が行われるので要注意。
具体例を示す。
Vector2d v0 = new Vector2d(1.0, 1.0); Vector2d v1 = new Vector2d(2.0, 1.0); ArrayList<Vector2d> array = new ArrayList<Vector2d>(); array.add(v0); System.out.println(array.contains(v1));
上記では、ArrayList に v0 を格納して、その後で、ArrayList に v1 が含まれるかどうかを確認している。
もちろん出力は
false
になる。
では、次のコードはどうだろう。先ほどのコードに対して、v1の座標値だけ変更した。
Vector2d v0 = new Vector2d(1.0, 1.0); Vector2d v1 = new Vector2d(1.0, 1.0); // ここだけ変更 ArrayList<Vector2d> array = new ArrayList<Vector2d>(); array.add(v0); System.out.println(array.contains(v1));
なんと出力は
true
になる。
ArrayList に含まれるか否かの判断は、オブジェクトとしてのVector2dではなく、その値の比較によって行われるということだ。
これを知らないでいると、たとえば、Vector2d をキーとした HashMapを作ってしまった場合などに、どつぼにはまることになる(私だ)。
詳しくは、Vector2dクラスのスーパークラスである Tuple2d のAPI仕様書をみると、次のように記述されていることから、値の比較によって行われることがわかる。
boolean equals(Tuple2d t1)
http://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/java3d/forDevelopers/j3dapi/javax/vecmath/Tuple2d.html
Returns true if all of the data members of Tuple2d t1 are equal to the corresponding data members in this Tuple2d.
つまり、ArrayList クラスの contains メソッドなどは、格納しているオブジェクトの equals メソッドを使って「同一オブジェクトであるか否か」の判断をしているが、
Vector2d クラスは、このequalsメソッドをオーバーライドしていて、ベクトルの2つの値が同じであるかによって判断されるようになっている。
ちなみに、Tuple2d クラスは、hashCode メソッドもオーバーライドしていて、ハッシュ値は内部の値によって生成されることになっている。
だから、HashMapのキーとして使うときは注意が必要だ(というか使うべきではない)。
int hashCode()
http://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/java3d/forDevelopers/j3dapi/javax/vecmath/Tuple2d.html
Returns a hash number based on the data values in this object.
コレクションクラスや、オブジェクトの equals メソッドのオーバーライドに関する話は、次の書籍に詳しく書かれている。
Java 2 アプリケーションづくりの初歩 (CD-ROM付) (プログラミング学習シリーズ)
- 作者: 三谷純
- 出版社/メーカー: 翔泳社
- 発売日: 2010/01/29
- メディア: 大型本
- 購入: 2人 クリック: 21回
- この商品を含むブログ (4件) を見る