【Java】入門!文字列を比較する!
  • facebookページ
  • twitterページ
  • 2019.10.30

    【Java】入門!文字列を比較する!”equals”と”==”の違いについて。

    今回は文字列の比較について、なぜequalsメソッドで比較するのかも踏まえて解説してみたいと思います。

    “equals”と”==”

    何はともあれ、まずはこの二つを使って比較してみましょう。

    まずはequalsメソッドから。

    実行結果

    上のコードは、三項演算子を使い呼び出し元の文字列の値と同一かどうかについての判定をBoolean型で出力させるだけの単純なコードです。

    equalsメソッドは引数に比較対象となる変数を指定し、呼び出し元の文字列の値が同一かどうかで比較します。

    今回の実験では変数fooに生成された文字列と変数barに生成された文字列が同一という判定が出ましたので、実行結果ではtrueとなっていることが分かります。

    では次に”==”を使って同じようなコードで実験してみましょう。

    実行結果

    コード内容はequalsと一緒ですが、一部”foo.equals(bar)”の部分を”(foo == bar)”としています。

    “equals”と”==”で同じ動作が期待できるのであれば、返ってくる値も同じであるはずなのに、今回はfalseとなってしまいました。

    この結果に混乱している方も多いと思いますので、次の項目では「Javaの参照について」の解説をしていきます。

    Javaの参照について

    Javaのデータ型にはプリミティブ型と参照型という二つの型が存在します。

    プリミティブ型とは次の8種類の型を指します。

    プリミティブ型

    左から「型名 – 分類 – サイズ(bit)」となっています。

    • long – 整数 – 64
    • int – 整数 – 32
    • short – 整数 – 16
    • byte – 整数 – 8
    • double – 少数 – 64
    • float – 少数 – 32
    • boolean – 真偽 – 無し
    • char – 文字 – 16

    これ以外の型は全て参照型となります。

    プリミティブ型の特徴としては、それ自体がメソッドを持っておらず、メモリに書き込まれるデータ値を代入することが出来る点です。

    これに対し参照型は、メモリにデータ値ではなくnew演算子で生成したオブジェクトのポインタ(アドレス)を参照値として代入しています。

    この違いを分かりやすく説明すると、参照型の場合はメモリ内部の動作として、まず格納されるデータのアドレスを決定し、その次に決定されたアドレスへデータを格納しています。

    このため、オブジェクトを生成した瞬間にメモリ上では一つの領域が確保され、その領域の中にデータを格納します。

    ですから次に参照する場合には、メモリは参照されたデータがどの領域に格納されているかを探し出すため、アドレスが違うとデータが同じでも”別物”として扱ってしまうわけです。

    “==”での比較は”equals”のように予め決められた動作ではなく漠然とした解釈での比較となる為、このような違いが出てきます。

    では次のコードではどうでしょう?

    実行結果

    今度は”true”となってしまいました。先ほどした説明だと矛盾してると思ってる方も多いはずです。

    しかし実は全く矛盾していません。この理由として今回のコードはnew演算子を使っておらず、参照型のStringにプリミティブ型のcharを代入しているだけだからです。

    少し例えを変えてご説明しましょう。

    “abc”さん夫妻が家を借りる時に別々に不動産屋さんに行った場合、同じ姓でも別世帯だと思われますよね?当然不動産屋さんは別々の部屋を用意します。まずこれが参照型の場合のメモリの動きです。

    では”abc”さん夫妻が一緒に不動産屋さんに家探しに行った場合、別々の部屋を用意するでしょうか?同じ家族ということが分かっているので通常は一つの家を用意します。これがプリミティブ型の場合のメモリの動きとなります。

    最後に記述したコード(new演算子を使っていない場合)では、メモリはまずcharというプリミティブ型の文字列を記憶し、そのデータ値をそれぞれの変数に代入しているためこのような結果となったわけです。

    このことから、正しく文字列の比較を行うためにはequalsメソッドを使うのが正しいということがお分かりいただけたと思います。

    equalsの注意点

    しかしequalsメソッドを使う場合にも注意は必要となります。

    まずは次のコードを見てみましょう。

    実行結果

    このように、比較する変数のどちらかが”null”となっていた場合、NullPointerExceptionが発生します。

    これを回避するためには、”==”を使い分岐文で予めnullチェックをするかObjects.equalsメソッドを使う必要がありますが、Objects.equalsメソッドを使う場合、比較する変数の両方がnullだった場合もtrueとなるため、状況によっては”==”を使って予めnullチェックをする方が賢明かもしれません。

    まとめ

    いかがでしたか?今回は文字列の比較について二つの方法の解説をしてみました。

    違いが分かっていなかった方もこの記事を読んで理解していただけると嬉しく思います。

    プリミティブ型と参照型のメモリ動作の違いについても、プログラミングの経験があまりない方はしっかりとした理解が出来ていない場合も多く見られますので、この機会にしっかりと理解を深めていきましょう。



    優良フリーランス案件多数掲載中!
    フリーランスエンジニアの案件をお探しなら
    ポテパンフリーランス

    この記事をシェア

    • Facebookシェア
    • Twitterシェア
    • Hatenaシェア
    • Lineシェア
    pickup









    ABOUT US

    ポテパンはエンジニアと企業の最適なマッチングを追求する企業です。

    READ MORE