[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10167] Re: equals() と ==



前橋です。

村山さん:
>たしかにintern()はStringでのみ提供されているメソッドだと
>思いますが,HashSetあたりを使えばそれと同等の処理を実装
>するのは難しくないと思います.それさえ実現すれば==はどの
>クラスのインスタンスでも使えるので実現可能なはずです.

intern()流の方法で、equals()を==で代用できるようにするには、
そのクラスがimmutableであるという前提が必要です。

>ちなみに,混乱するというのならクラスによって挙動が変化する
>equals()の方が混乱するのでは.
<引用順変えてます>
>                                            これに対し
>==の方はクラスに関係なく同じ動作をしますから,混乱する
>ことはないでしょう.

だからって「==」が役に立つとは限らないのでは? 意味が全然
違うのですから。

>                              Stringや数値以外では同値の
>定義ができず,実質利用価値はないでしょう.それこそString
>以外のクラスのインスタンスでequalsを積極的に利用した人
>なんて,ほとんどいないんじゃないでしょうか.

私がよく使うのは、何かをidentifyするクラスですかね。

class Name {
    String familyName;
    String firstName;
}

とか。

また、たとえばファイルシステムを作るなら、「パス名」なども、
ひとつのStringで実現するのではなく、Stringのリストにしたいで
すよね。同値比較を行う局面もちょくちょくありそうです。

まあ、これぐらいのクラスなら、immutableにして、intern()と同
等の手法で==で比較するようにすることも可能ですが、そのための

・コーディングのコスト
・intern()時の比較のコスト
・オブジェクトプールのコスト

と、== に置き換えることによる効率化とのトレードオフを考える
必要があるでしょう。

この場合のオブジェクトプールって、増えっぱなしになりますよね。

>> 私的には、「文字列の内容を比較したいのなら何も考えずに
>> equals()を使えばいいじゃん」と思います。
>あげ足を取るつもりはないですが,Stringの『内容』を比較したい
>のなら==は使えないので,equals()を使うほかありません.もっとも
>equals()自体は必ずしも内容を比較するメソッドではないですが.

文字列について、そのオブジェクト自体の同一性を調べることなん
てあるんでしょうか? 文字列比較はほぼ常に「内容の比較」だと思
うのですが。

で、Stringはたまたまimmutableで、intern()という機構もあるから、
(注意深くやれば) ==でequals()を「代用」できるというだけで、
これは単なる高速化の一技法だと思います。速度を気にしないので
あれば、equals()を使うのが自然な場面ですよね。

だから、速度をよほど気にする場合以外は、私は『何も考えずに
equals()を使えばいいじゃん』と思います。所詮「みみっちい最適
化」の範疇なのでは?

>「内容を比較するアルゴリズム」が本質的に遅く,もっと高速
>なアルゴリズムに変更しなければならない場合も出てくる.その
>常套手段がintern()と==を使う方式というだけで,その他のやり方
>をしちゃいけないわけではない.本質はアルゴリズムの最適化で
>あって,内容の比較から参照の比較への置き換えというのは,
>その実現法の一つに過ぎません.

そのとおりです。

>> そういや、デシリアライズで発生したStringオブジェクトって、
>> intern()されるんでしたっけ?
>#されないからこそ,偽者が発生するという話なのでは.

だから、速度を気にしない限り『何も考えずにequals()を使う方が
安全』と言っているのです。最適化がどうしても必要な場面でなら、
intern()して==という手も、もちろんアリだと思いますけどね。

>#やりたければプログラマーが明示的に宣言するんでしょう.

やりたければプログラマがreadObject()を「忘れずに」実装するん
でしょう。いかにも忘れそうですが。

==で文字列を比較するということは、ユーザがTextFieldから入力
した文字列、StringTokenizerとかで切り出した文字列、ファイル
から読み込んだ文字列、それら「全て」について、「忘れずに」
intern()することを強制します。私はあまりやりたくありません。

>>明らかにcomposite複合クラス同士の比較は手作りのequals()
>>でなければ実現不可能ですから。
>
>equals()はデフォルト実装("==")でも特に問題ないはずですが.

ありまくりでしょう。意味が全然違うんですから。

>それに,実際問題としてあまりに複雑なインスタンス同士の
>「同値」は容易には定義できない場合が多いのでは.

まあ、これは確かにそうかもしれませんが。

------------------------------------------------------------
  前橋 和弥              PXU00211@xxxxxxxxxxx
                         http://member.nifty.ne.jp/maebashi/
------------------------------------------------------------