• ベストアンサー

オブジェクトの比較と文字列の比較の違い

今、基本情報技術者の勉強でJavaを勉強しているのですが、持っているテキストの問題で分からないものがありました。 String str1 = "Hello."; String str2 = "Good, Bye."; String str3 = str1; String str4 = str1 + str2; とすると、 (A)str1 == str2; がfalse (B)str1.equals(str3); がtrue というのは分かるのですが、 (C)str4 == "Hello.Good, bye."; がなぜfalseになるのでしょうか? ==はオブジェクトの比較で、equlasは文字列の比較だと書いているのですが、よく違いが分かりません。 また、 上の4つの処理の後に str3 = "test"; という処理を行っているのですが、このときの状況は、 str1はHello.のままで、 str3のみがtestになっている、と理解したのですがそれで合っているのでしょうか?

  • fuyu
  • お礼率69% (145/210)
  • Java
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.2

Java は、オブジェクトの置き場所を仮想マシン(Java のシステム、位の理解で良いです)が 管理しています。オブジェクトの内容を書き込める分厚いノートがある、と想像して下さい。 Java で扱うオブジェクトは、全て「参照」です。そのノートのページ番号が「参照」である と理解して下さい。 > String str1 = "Hello."; これは、新しい1ページを見つけて、String のオブジェクトであることと、その内容が "Hello." である事を書き込んで、そのページ番号を str1 という変数に覚えておきます。 > String str3 = str1; これは、str1 に書いてあるページ番号を str3 に書き移していることになります。 "Hello." と書いてあるノートのページは、未だひとつしかありません。 > ==はオブジェクトの比較で、equlasは文字列の比較だと書いているのですが、よく違いが分かりません。 == は、(ここまでの喩えの)ページ番号の比較で、equals は、ページに書き込まれている内容の 比較になります。 > String str4 = str1 + str2; これは、str1 のページの内容と str2 のページの内容をくっつけたものを、新しいページを 探して、そこに書き込み、そこのページ番号を str4 に覚えておきます。 > (C)str4 == "Hello.Good, bye."; で、この式は、さっきのページ番号と、(新しくページを探して)"Hello.Good,bye" と書き込んだ ページの番号を比べていることになります。なので、ページ番号が違う、ということで false に なります。 > str3 = "test"; > という処理を行っているのですが、このときの状況は、 > > str1はHello.のままで、 > str3のみがtestになっている、と理解したのですがそれで合っているのでしょうか? 合ってます。 > str3 = "test"; は、新しいページを探して、"test" という内容を書き込んで、そのページ番号を str3 に 覚えておくことになります。"Hello." が書いてあるページ番号が消されてしまいますが、 そのページに対して何かを書いたり・消したりしているわけではないので、str1 に入っている ページ番号のページには "Hello." がそのまま残っています。 > str3のみがtestになっている と言うよりは、str3 が "test" という内容の String オブジェクトを「指している」と いう言い方が正確な表現になります。

fuyu
質問者

お礼

御礼が遅くなり申し訳ありません。 今回は回答ありがとうございました。 非常に分かりやすい説明で、==とequalsの 働きなどがイメージしやすく、理解が 深まったと思います。 ありがとうございました。

その他の回答 (1)

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.1

"Hello" と "Hello" は同じでしょうか。 よく見て下さい。もちろん、文字列としては同じです。 けれども、書かれている場所が違います。最初のものは 左に、次のものは右に書かれています。 トンチクイズではありません。==による比較は、こんなこと まで比較するのです。ですから、例えばstr1もstr2も同じ 左側の"Hello"を指すとすれば、(str1==str2)はtrueです。 しかし、str1が左側の"Hello"を、str2が右側の"Hello"を 指すとすれば、(str1==str2)はfalseになってしまいます。 (str1.equals(str2)はtrueです。) ご質問のケースでは、str1+str2でStringオブジェクトが 作られていますが、(C)の右辺にある"Hello.Good, bye." は、それとは別の場所にあるのです。

fuyu
質問者

お礼

御礼が遅くなり申し訳ありません。 今回は、回答ありがとうございました。 おかげさまで理解できました。

関連するQ&A

  • 文字列の比較

    いつも参考にさせて頂いています。 基本的なことなのですが、宜しくお願いします。 たとえば文字列"str"の空チェックをするとします。 -------------------以下参考ソース String str = "test"; 1. public static String isBlank(String str) { if(str == null || str.equals("")) { return true; } return false; } 2. public static String isBlank(String str) { if(str == null || str.length = 0) { return true; } return false; } ■1と2の違いって何かありますでしょうか? ■空チェックなら1と2のどちらを使うべきでしょうか? 以上宜しくお願いします。

    • ベストアンサー
    • Java
  • 参照型変数の比較について

    1,2のソースについての質問となります。 ご教授の程お願い致します。 ◇◆1◆◇ class Sample{ public static void main(String args[]){ String s1 = "Hello"; String s2 = "Hello"; String s3 = new String("Hello"); System.out.println(s1 == "Hello"); //(1) } } ◇◆2◆◇ class Sample{ public static void main(String args[]){ String s1 = "Hello!Java"; String s2 = s1; s1 = s1.substring(6); //(2) System.out.println(s1); //(3) System.out.println(s2); //(4) } } ○1の質問 (1)の部分になりますが、 「s1 == "Hello"」の結果がtrueとなる理由が理解しずらいです。 「==」演算子では、「同じオブジェクトを参照しているか」を 比較するものであって、この場合「オブジェクトと文字列」の比較を しているので、falseになると思われます。 仮に、Helloがオブジェクトとして捉えられている場合であっても 「String s3 = new String("Hello");」で作成されたオブジェクトを 参照しているものとなるので、s1と比較をしてもfalseになると 思われます。 ○2の質問 このソースを実行後、 Java Hello!Java と、出力される理由についての質問となります。 (2)で「Java」の文字列を返し、s1に代入されますが、 s2はs1の参照型であるため、「Hello!Java」から「Java」に 変わると思われます。実際には、 Java Java と、出力されると思われます。 以上、わかりにくい箇所があると思われますが、 ご教授の程お願い致します。

    • ベストアンサー
    • Java
  • 文字列の比較をしたい

    String str1 = "北海道" String str2 = "北海道" str1とstr2が同じ場合にある処理をしたい場合、比較のところの記述はどのように書けばよいのでしょうか。 単純に If str1 = str2 Then ~~~~~ Else   ~~~~ End If でよいのでしょうか。 環境はVB.NETです。

  • 文字列の配列の比較

    こんにちは。タイトルどおり簡単な質問なのですが、どうしても確認したいのでお願いします。 とあるメソッドで、2次元配列の中にいくつか大文字のOが入ってるのですが、与えられた配列にOがあればtrueを返し、なければfalseを返します。 public boolean cellAt(int row, int col){ if(space[row][col].equals("O")) return true; else return false; } rowとcolはテストメソッドから値を受け取ります。 これでプログラム自体は動くのですが、WebCatという自動的に採点するものがあるのですが、それによるとエラーがでてしまいます・・・。 どこが違うのかは教えてくれないのですが・・・。 上で間違っているとすれば、文字列の比較くらいしかないんじゃないかと思うのですが、 space[row][col].equals("O") これで比較できますよね? 他のを調べて、if (Arrays.equals(space[row][col], "O"))これを試してもみたのですが、赤線が出てしまって無理でした。 どなたか宜しくお願いします。

  • 文字列の比較について

    BufferedReaderでファイルを読んだのちに、見出しの文字列をカンマで分割して 文字列を比較しようとしています。 ですが、分割すると、文字列が別な文字コードによる表記に変わってしまいます。 なぜでしょうか? また、解決方法などのヒントなどあれば教えてください。 BufferedReader buffReader = new BufferedReader( new FileReader("/home/masa/Desktop/Sample.csv")); String s; int ini=0; int wamei=0; int i=0; while((s = buffReader.readLine())!= null){ String[] str = s.split(",", -1); //System.out.println(s); if (i == 0) { for(int j=0; j<str.length;j++){ System.out.println(String.toString(str)); if(str.equals("五十音")){ini = j;} System.out.println("五十音"+ini); if(str.equals("a")){wamei = j;} System.out.println("和名"+wamei); //System.out.println(j); } } i++;

    • ベストアンサー
    • Java
  • Javaの文字列比較

    初歩的な質問ですが、Javaで文字列比較は moji == hikaku でなくて moji.equals(hikaku)でないとダメなのでしょうか? 仕様やオブジェクト指向だからでなく、具体的な理由が知りたいです。 数年後には理解できるかもしれませんので難しくても構いません。

    • ベストアンサー
    • Java
  • C#で char型とstring型の比較で Equalsでハマりました。 

    C#で char型は値型でstring型は参照型ですがこの比較を正しく行うにはどうしたらよいでしょうか? string s = "0123456789"; Console.WriteLine(s[0]); Console.WriteLine("0".Equals(s[0]) ? "true" : "false"); で、falseなのは驚きでした。 Equalsを鵜呑みにしていました。 コンパイルできたので今まで気づきませんでした。 詳しい方、教えて頂けますか?

  • バイナリ文字列の比較について

    テキストをバイナリで読み込んで文字列を比較する際に 下記のロジックだと2バイトずつ読み込んで比較していくのですが 比較したい文字列が"He"だと合致するのですが1バイトずれの "el"だと合致しません。 ストリーム内の任意の文字列を判定したいときはどのように修正すればよいでしょうか? ----sample.txt--- Hello World!! ---------------- byte[] buf = new byte[2]; FileInputStream in = new FileInputStream("sample.txt"); int b; while ((b = in.read(buf)) != -1) { if ("He".equals(new String(buf))) { System.out.println("HelloのHeはOK"); } if ("el".equals(new String(buf))) { System.out.println("HelloのelはNG"); } }

    • ベストアンサー
    • Java
  • Java ファイルオブジェクトでなく文字列オブジェクト?

    JavaでXMLをパースするプログラムを初めて試しています。 parseメソッドの第一引数がファイルオブジェクトなのですが、これをメモリ(文字列)オブジェクトを与えて同じ動作させるものはあるのでしょうか? // SAXパーサーファクトリを生成 SAXParserFactory spfactory = SAXParserFactory.newInstance(); // SAXパーサーを生成 SAXParser parser = spfactory.newSAXParser(); // XMLファイルを指定されたデフォルトハンドラーで処理します parser.parse(new File("helloworld.xml"), new InsXMLParser()); ※このように String str = "<xml? ......"; parser.XXXXXX(str, new InsXMLParser

    • ベストアンサー
    • XML
  • 文字列で渡された式

    質問です。 タイトルのままですが文字列で渡された式で 処理を決定させることはできるのでしょうか? たとえば ============================ dim str as string = "10 > 5" if strの文字列判定 then msgbox("TRUE") else msgbox("FALSE") end if ============================