JAVAの質問です。(equalメソッドについて教えて下さい)



下記のロジックでは、execute()は実行されることはないですよね?
("".equals(list)は、必ず偽となりますよね?)

-----------------------------------
Collection list = new ArrayList();
if("".equals(list)){
execute();
}
-----------------------------------


「"".equals(list)」の意味は、
String型の文字列「""」と、Collectionの「オブジェクトの識別値の文字列(String型)?」を比較しているのでしょうか?
("".equals(list.toString())と同じでしょうか?)


②について書籍やWEBで調べたいのですが、どこを見ればいいか分かりませんでした。
参考になるのがあれば教えて下さい。

以上です。上記3点のうち1つでも結構ですので、アドバイスを頂ければ助かります。

回答の条件
  • 1人10回まで
  • 登録:
  • 終了:2008/09/30 07:45:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答4件)

id:ahirusan No.1

回答回数229ベストアンサー獲得回数3

ポイント23pt

Javaのequalメソッドはオブジェクト同士が同じ参照を持っているかどうかを比較するメソッドです。なので、当然上記コードはfalseとなり、execute()は実行されません。

Javaチュートリアル 第4版 (The Java Series)

Javaチュートリアル 第4版 (The Java Series)

  • 作者: シャロン ザクァワ ジャコブ ロイヤル アイザック ラビノビッチ マーク ホーバ トーマス リーサ スコット ホンメル
  • 出版社/メーカー: ピアソンエデュケーション
  • メディア: 単行本

②に関しての解釈はあっています。""文字列とlist.toString()の結果が等しいかどうかを判定しています。

id:nemutaiyo

ありがとうございます。紹介頂いた本を読んで、基本から学びなおします。

2008/09/23 11:27:46
id:b-wind No.2

回答回数3344ベストアンサー獲得回数440

ポイント23pt

下記のロジックでは、execute()は実行されることはないですよね?

("".equals(list)は、必ず偽となりますよね?)

yes

「"".equals(list)」の意味は、

String型の文字列「""」と、Collectionの「オブジェクトの識別値の文字列(String型)?」を比較しているのでしょうか?

("".equals(list.toString())と同じでしょうか?)

No

http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/String.htm...(java.lang.Object):title]

String クラスで定義されている equals は比較対象も String クラスであり、かつ文字列として同等である必要がある。

②について書籍やWEBで調べたいのですが、どこを見ればいいか分かりませんでした。

参考になるのがあれば教えて下さい。

equals メソッドは何か特別なものではなく、普通にメソッドとして定義されているものなので

それぞれのクラスの API ドキュメントを見てください。ドキュメントがなければソースコードを読むしかないですが。


それぞれのクラスによって実装は違うのでたとえば以下の結果が真になることはあり得ます。

MyClass obj = new MyClass("文字列");
if ( obj.equals("文字列") ) {
  System.out.println("真");
}

これは MyClass の equals メソッドでそう実装されている場合です。

また、各クラスで equals を実装しなかった場合は大本である Object クラスの equals が呼び出されます。

http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/Object.htm...(java.lang.Object):title]

ここには equals メソッドを実装する場合のルールが書かれていますが、その通りであるかは実装した側のクラス定義次第です。

id:nemutaiyo

ありがとうございます。

>それぞれのクラスによって実装は違うのでたとえば以下の結果が真になることはあり得ます。

すみません。言葉足らずでした。

「Stringクラスのequalメソッドについて、教えて下さい」と書くべきでした。

2008/09/23 11:32:35
id:quintia No.3

回答回数562ベストアンサー獲得回数71

ポイント22pt

> 「Stringクラスのequalメソッドについて、教えて下さい」と書くべきでした。

StringクラスのequalsメソッドのAPI仕様を読むべきでしょう。


この文字列と指定されたオブジェクトを比較します。引数が null でなく、このオブジェクトと同じ文字シーケンスを表す String オブジェクトである場合にだけ、結果は true になります。

http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/String.htm...

とあるので、true になるのはメソッド引数が「String オブジェクトある」必要があることが分かります(「同じ文字シーケンスを表す StringBuffer」では駄目なわけですね)。


ところで、日本語訳だと「String オブジェクトでなければならない」とパッと見で分からない文になってしまっています。

妙だと思ったら英語のドキュメントも読むべきだと、私は思います。

Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object

http://java.sun.com/javase/6/docs/api/java/lang/String.html#equa...

"if and only if the argument is not null and is a String object that ~"という形式なので明確です。

これを訳したときに、単語の順番が逆になって分かりづらくなっています。


不明な点は、日本語APIドキュメント → 英語APIドキュメント の順に確認していくといいでしょう。

id:nemutaiyo

>不明な点は、日本語APIドキュメント → 英語APIドキュメント の順に確認していくといいでしょう。

了解です。質問する前に日本語APIを呼んだのですが、明確に分からなかったので質問しました。今後は英語APIも見ます。

ahirusanさんから、

>②に関しての解釈はあっています。""文字列とlist.toString()の結果が等しいかどうかを判定しています。

と回答頂きました。

つまり、条件としては、NULLでない→OK。Stringである→OK。同じシーケンス(文字列)である→NG ⇒結果False になる。ということですよね。

#疑問が少しあります。

自動的にtoString()されるのは、Stringクラスのequalsメソッドだからでしょうか?(例えば、list.equals(list)の場合は、toString()はされない?)またlist.toString()の文字列が""になることはないのでしょうか?

2008/09/23 23:43:30
id:newta No.4

回答回数68ベストアンサー獲得回数7

ポイント22pt

String の equalsメソッドのソースはこうみたいですよ。

    public boolean equals(Object anObject) {
		if (this == anObject) {
		    return true;
		}
		if (anObject instanceof String) {
		    String anotherString = (String)anObject;
		    int n = count;
		    if (n == anotherString.count) {
			char v1[] = value;
			char v2[] = anotherString.value;
			int i = offset;
			int j = anotherString.offset;
			while (n-- != 0) {
			    if (v1[i++] != v2[j++])
				return false;
			}
			return true;
		    }
		}
		return false;
    }

簡単そうならばドキュメント探して解釈をうーむと悩むよりも

ソースを見てしまったほうがスパッと分かると思いますよ。

オープンソースならばどんどんソースを見て行きましょうー

id:nemutaiyo

ありがとうございます。equalsメソッドの中身もデバッグで追ってみると、

if (anObject instanceof String) がfalseになり、

return false;が返りました。

つまり、anObjectオブジェクトはStringでない!ということがわかりました。(toString()されていない!)

>オープンソースならばどんどんソースを見て行きましょうー

おっしゃるとおりだと思いました。

2008/09/24 21:36:54
  • id:b-wind
    >「Stringクラスのequalメソッドについて、教えて下さい」と書くべきでした。
    ですので、String クラスの API ドキュメントのリンクを貼ってあります。

    該当部分以下は補足説明です。
  • id:Horiuchi_H
    "".equals(list) と "".equals(list.toString()) は等価ではありません。
    "[]".equals(list) と "[]".equals(list.toString()) のそれぞれを実行すると、後者だけ trueになります。
  • id:quintia
    2.の回答で b-wind さんは、1.の回答を否定していますよね?
    私はその流れで 3. の回答をしています。
    Horiuchi_H さんがコメントされている通り、「自動的にtoString()」などされません。
  • id:nemutaiyo
    Horiuchi_Hさん、quintiaさん
    コメントありがとうございます。
    >2.の回答で b-wind さんは、1.の回答を否定していますよね?
    すみません。誤った理解をしておりました。(つまり、toString()はされるけど、その文字列が違う。だからfalseになる。と思っていました。)
    回答4に書きましたが、toString()されないことが確認できました。

    度々の質問で申し訳ないですが、あと1点だけ教えて下さい。
    >"[]".equals(list) と "[]".equals(list.toString()) のそれぞれを実行すると、後者だけ trueになります。
    これは理解できました。
    あと、"[]" についてですが、空のCollectionオブジェクトをtoString()すると、"[]"になるのでしょうか?(値が入れば、Collection@ハッシュ のような値になると以下に書いてありました。http://www.lcv.ne.jp/~kenmio/yomimono/yomimono18.htm)

    newtaさんのアドバイスどおり、Collectionのソースを見てみますが、
    もしご存知であれば教えて下さい。(コメントでは申し訳ないので、回答の法にお願いします。)
  • id:nemutaiyo
    すみません。自己解決したかもしれません。
    #
    >このコレクションの文字列表現を返します。文字列表現は、コレクションの要素をその反復子が返した順に角括弧 ("[]") で囲んで示すリストです。
    http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/AbstractCollection.html#toString()
    #
    リストに要素が1件もないから、ただの"[]"になるのですね。理解しました。
    上で、Collection@ハッシュうんむんと書きましたが、これはtoString()の結果ではなく、オブジェクトの識別値だと思います。同じオブジェクトかどうかの比較(おそらく==)で利用して、equalsでは利用しないと認識しています。
  • id:b-wind
    >このコレクションの文字列表現を返します。文字列表現は、コレクションの要素をその反復子が返した順に角括弧 ("[]") で囲んで示すリストです。
    http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/AbstractCollection.html#toString()
    半分本当で半分間違い。
    それは AbstractCollection#toString() の実装がそうなっているだけ。
    Collection はインターフェイスだけを定義しているので、実装はクラスによって違う。
    AbstractCollection のサブクラスであれば、同じ表記になることも多いだろうが独自に実装する場合もあるので、
    Collection すべてに対して必ずしも "[]" と表現されるわけではない。

    >Collection@ハッシュうんむんと書きましたが、これはtoString()の結果ではなく、オブジェクトの識別値だと思います。同じオブジェクトかどうかの比較(おそらく==)で利用して、equalsでは利用しないと認識しています。
    どっからどうやったら勝手に == と結び付けているのやら。

    == 演算子はオブジェクトの場合、純粋に「同じオブジェクトの参照」かどうかだけを比較している。
    文字列評価がどうなろうが、違うオブジェクトの場合は false になる。

    一方 Collection#hashCode (多分これのことを指しているとして説明する)の使い道は
    http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/Collection.html#hashCode()
    たとえば HashMap オブジェクトのキーに使用する場合などに使われる。
    この場合、全く同一のオブジェクトでなくとも内容的に等価なオブジェクトであれば同じキーとしてみなさないと
    利便性が悪いから。そのあたりの話は以下のリファレンス参照。
    http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/index.html?java/util/Collection.html
  • id:nemutaiyo
    >Collection すべてに対して必ずしも "[]" と表現されるわけではない。
    理解しました。

    >== 演算子はオブジェクトの場合、純粋に「同じオブジェクトの参照」かどうかだけを比較している。
    >文字列評価がどうなろうが、違うオブジェクトの場合は false になる。
    これも了解しました。
    が..まだ明確に理解できていません。基本から勉強しなおします。
    いろいろありがとうございました。勉強の必要性を感じました。
    また次回質問させて頂くときも、是非ご教授ください。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません