- PR -

文字列配列の比較

1
投稿者投稿内容
KORO
会議室デビュー日: 2003/06/01
投稿数: 4
投稿日時: 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メソッドを使ってみたのですが思うような
結果が得られませんでした。。
何か良い判断方法をご存知の方がいらっしゃいましたら
ご教授いただきたいと思います。
宜しくお願い致します。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-06-01 23:52
unibon です。こんにちわ。

引用:

KOROさんの書き込み (2003-06-01 23:19) より:
Java初心者のため良い方法がわかりません。。
equalsメソッドを使ってみたのですが思うような
結果が得られませんでした。。


どのように試されて、どのような結果を期待され、実際はどのような結果が得られたのかを
具体的に書かれたほうが良いですよ。

基本的には equals でうまく行くはずです。サンプルとしては、
コード:
import java.util.*;

public class ListTester {
    public static void main(String[] args) {
        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"); 

        boolean bXY = vXData.equals(vYData);
        System.out.println("bXY = " + bXY);

        List vZData = new ArrayList(); 
        vZData.add("d"); 
        vZData.add("a"); 
        vZData.add("x"); 
        vZData.add("z"); 
        boolean bXZ = vXData.equals(vZData);
        System.out.println("bXZ = " + bXZ);
    }
}



ではうまくいくようです。

余談になりますが、たまたまですが、
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 が使われますので、
副作用が大きすぎて使いにくいと思います。
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-06-02 09:33
こんにちは、Wataです。

引用:

なお、List(ArrayList) や JDK 1.2 以上での Vector における、
この equals の仕様は、やりすぎのような気がします。
このような比較をやることって、そうそうあるんでしょうか。
たしかに、簡便に比較できて便利とは言えば便利なのですが、
List/Set/Map のキーとして使うときにもこの equals が使われますので、
副作用が大きすぎて使いにくいと思います。



同感です。さらに私の場合ですと、immutableでないオブジェクト
にequals(hashCode, compareToも同様)メソッドを実装すること
自体あまりよくないような気がします。
HashMapなどのキーに使った後でequalsメソッドに影響を及ぼすような
変更をすると、キーに当てられた値は迷子になってしまいますからね。

#まあ、キーに使う予定がなければ別にいいのかな?

こう考えると、TreeMapにComparetorを指定するように、
HashMapにもハッシュコード生成とequals比較を代行する
オブジェクトを指定できてもいいような気がします。
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2003-06-02 13:44
引用:

なお、List(ArrayList) や JDK 1.2 以上での Vector における、
この equals の仕様は、やりすぎのような気がします。
このような比較をやることって、そうそうあるんでしょうか。
たしかに、簡便に比較できて便利とは言えば便利なのですが、
List/Set/Map のキーとして使うときにもこの equals が使われますので、
副作用が大きすぎて使いにくいと思います。



List を key や value に使う Map など、Collection をネストさせた集合を使うときに、このような仕様でないと困ってしまうような気がしますが...。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2003-06-03 15:23
引用:

unibonさんの書き込み (2003-06-01 23:52) より:
なお、List(ArrayList) や JDK 1.2 以上での Vector における、
この equals の仕様は、やりすぎのような気がします。
このような比較をやることって、そうそうあるんでしょうか。
たしかに、簡便に比較できて便利とは言えば便利なのですが、
List/Set/Map のキーとして使うときにもこの equals が使われますので、
副作用が大きすぎて使いにくいと思います。



そうですか?私は値比較の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では配列もオブジェクトですけど)
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-06-03 15:58
unibon です。こんにちわ。

引用:

H2さんの書き込み (2003-06-03 15:23) より:
そうですか?私は値比較のequalsの方が正しいと思いますが・・・。その方がより論理的ではないでしょうか?でもよく考えたらあまりコンテナや配列が等しいかの判定というのはめったに行わないです。今まで気づきもしませんでした


確かに、理論的なキレイさから言えばそう(値比較が正しい)なのかもしれません
(なお、後述の配列の判定の問題はありますが)。

引用:

H2さんの書き込み (2003-06-03 15:23) より:
ところで、VectorやListをList/Set/MapのKeyとして使うというのはどういう状況でしょうか?個人的な経験からVectorやListのようなものはKeyに使ったことも、使おうと思ったこともありません。後学のために教えていただけないでしょうか?


私も、アプリケーションの主たる機能のために List/Set/Map を
キーに使おうとしたことはありませんでしたが、
先日、デバッグ用途として、プログラム中で new した任意のインスタンス(List/Set/Map)を
(管理用の特定の) List/Set/Map に蓄積して管理しようとして、
このような equals の仕様であることに気づかずに、はまり
しばらく悩んでやっと気づきました。

引用:

H2さんの書き込み (2003-06-03 15:23) より:
#細かい事を突っ込んでしまいますが、ArrayListやVectorはコンテナです。配列ではありません・・・。(といってもJavaでは配列もオブジェクトですけど)


以下、揚げ足とりみたいになって申し訳ないのですが、
これを拝見して、ふとつぎのようなことを試してみました。
コード:
public class ArrayTester {

    public static void main(String[] args) {
        int[] a = new int[2];
        a[0] = 123;
        a[1] = 456;
        int[] b = new int[2];
        b[0] = 123;
        b[1] = 456;
        boolean e = a.equals(b);
        System.out.println("e = " + e);
    }
}


結果は 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[])
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2003-06-04 07:38
引用:

unibonさんの書き込み (2003-06-03 15:58) より:
unibon です。こんにちわ。

以下、揚げ足とりみたいになって申し訳ないのですが、
これを拝見して、ふとつぎのようなことを試してみました。

・・・

結果は 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[])


そうですね。配列とコレクション(もしくはコンテナ)は基本思想が違いますからね。昔の昔に戻りますが、Cでは配列はただのメモリアドレスとそこからのオフセット(差分)という考えでした。Cでarray[4] を *(array + 4) と書けるのはこのためです。そのため、二つの配列を比べるときは配列の内容ではなく頭のアドレスの値を比べる、つまりJavaでは参照比較になるのだと思います。

Linked Listなどのコレクション系はメモリ上の配置からの独立性を高めるためメモリアドレスとオフセットというものとはまったく違う形で提供されています。そのため値比較のほうが適当に思えるのだと思います。
1

スキルアップ/キャリアアップ(JOB@IT)