- - PR -
文字列配列の比較
1
| 投稿者 | 投稿内容 | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-06-01 23:19
お世話になります。
2つの配列に1次元の文字列配列を格納してるのですが、 その2つの配列の内容(サイズ、要素)が一致しているか 確認するのにはどのような方法がありますか? List vXData = new ArrayList(); List vYData = new ArrayList(); vXData.add("a"); vXData.add("b"); vXData.add("c"); vYData.add("a"); vYData.add("b"); vYData.add("c"); の場合にvXDataとvYDataを比較した場合 一致と判断し、vYDataが以下の場合は vYData.add("d"); vYData.add("a"); vYData.add("x"); vYData.add("z"); 不一致と判断したいのです。 Java初心者のため良い方法がわかりません。。 equalsメソッドを使ってみたのですが思うような 結果が得られませんでした。。 何か良い判断方法をご存知の方がいらっしゃいましたら ご教授いただきたいと思います。 宜しくお願い致します。 | ||||||||||||||||
|
投稿日時: 2003-06-01 23:52
unibon です。こんにちわ。
どのように試されて、どのような結果を期待され、実際はどのような結果が得られたのかを 具体的に書かれたほうが良いですよ。 基本的には equals でうまく行くはずです。サンプルとしては、
ではうまくいくようです。 余談になりますが、たまたまですが、 JDKバージョン互換の落とし穴(旧件名:Colorクラスの落とし穴) http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3770&forum=12&8 でも書きましたが、もし List(ArrayList) ではなく Vector を使うと、 equals の仕様が違うので、バージョンによっては期待通りの結果が得られないことがあります。 なお、List(ArrayList) や JDK 1.2 以上での Vector における、 この equals の仕様は、やりすぎのような気がします。 このような比較をやることって、そうそうあるんでしょうか。 たしかに、簡便に比較できて便利とは言えば便利なのですが、 List/Set/Map のキーとして使うときにもこの equals が使われますので、 副作用が大きすぎて使いにくいと思います。 | ||||||||||||||||
|
投稿日時: 2003-06-02 09:33
こんにちは、Wataです。
同感です。さらに私の場合ですと、immutableでないオブジェクト にequals(hashCode, compareToも同様)メソッドを実装すること 自体あまりよくないような気がします。 HashMapなどのキーに使った後でequalsメソッドに影響を及ぼすような 変更をすると、キーに当てられた値は迷子になってしまいますからね。 #まあ、キーに使う予定がなければ別にいいのかな? こう考えると、TreeMapにComparetorを指定するように、 HashMapにもハッシュコード生成とequals比較を代行する オブジェクトを指定できてもいいような気がします。 | ||||||||||||||||
|
投稿日時: 2003-06-02 13:44
List を key や value に使う Map など、Collection をネストさせた集合を使うときに、このような仕様でないと困ってしまうような気がしますが...。 | ||||||||||||||||
|
投稿日時: 2003-06-03 15:23
そうですか?私は値比較のequalsの方が正しいと思いますが・・・。その方がより論理的ではないでしょうか?でもよく考えたらあまりコンテナや配列が等しいかの判定というのはめったに行わないです。今まで気づきもしませんでした で、ちょっと興味が湧いたので久々にJDK1.xのドキュメントを読みました。4年前Javaをはじめた頃のことを思い出してちょっと懐かしいです 笑。 ところで、VectorやListをList/Set/MapのKeyとして使うというのはどういう状況でしょうか?個人的な経験からVectorやListのようなものはKeyに使ったことも、使おうと思ったこともありません。後学のために教えていただけないでしょうか? なお、私はKeyとして使うものはできるだけ Type Safe Enumeration系(もしくはprimitive、String)のimmutableなものを使っています。ちょっとでも中身を変えたらhashCode()の値が変わってしまうので、VectorやListはもちろん、mutableな物はKeyとして使うべきではないと思うのですが。 #細かい事を突っ込んでしまいますが、ArrayListやVectorはコンテナです。配列ではありません・・・。(といってもJavaでは配列もオブジェクトですけど) | ||||||||||||||||
|
投稿日時: 2003-06-03 15:58
unibon です。こんにちわ。
確かに、理論的なキレイさから言えばそう(値比較が正しい)なのかもしれません (なお、後述の配列の判定の問題はありますが)。
私も、アプリケーションの主たる機能のために List/Set/Map を キーに使おうとしたことはありませんでしたが、 先日、デバッグ用途として、プログラム中で new した任意のインスタンス(List/Set/Map)を (管理用の特定の) List/Set/Map に蓄積して管理しようとして、 このような equals の仕様であることに気づかずに、はまり しばらく悩んでやっと気づきました。
以下、揚げ足とりみたいになって申し訳ないのですが、 これを拝見して、ふとつぎのようなことを試してみました。
結果は false (すなわち等しくない)になります。 すなわち、配列とコレクション API では equals の仕様が異なることになります。 もちろん java.util.Arrays クラスの equals メソッドは、ちゃんと用意されてはいるのですが。 http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/util/Arrays.html#equals(int[], int[]) | ||||||||||||||||
|
投稿日時: 2003-06-04 07:38
そうですね。配列とコレクション(もしくはコンテナ)は基本思想が違いますからね。昔の昔に戻りますが、Cでは配列はただのメモリアドレスとそこからのオフセット(差分)という考えでした。Cでarray[4] を *(array + 4) と書けるのはこのためです。そのため、二つの配列を比べるときは配列の内容ではなく頭のアドレスの値を比べる、つまりJavaでは参照比較になるのだと思います。 Linked Listなどのコレクション系はメモリ上の配置からの独立性を高めるためメモリアドレスとオフセットというものとはまったく違う形で提供されています。そのため値比較のほうが適当に思えるのだと思います。 | ||||||||||||||||
1
