1

I have a situation of appending String. And i'm confused ..

   public static void foo() {
       String s = "str4";
       String s1 = "str" + s.length();
       System.out.println("(s==s1) = " + (s1 == s));
   }

And

    public static void bar() {
       String s = "str4";
       String s1 = "str" + "4";
       System.out.println("(s==s1) = " + (s1 == s));
    }

In 1st case it's returning 'false' but in 2nd case 'true' As i understand in both cases 'str4' object is being created on the heap. So it should return true in both cases. But it's not. Kindly someone help me out why it's so. ? Thanks.!

cypheon
  • 1,023
  • 1
  • 13
  • 22
Aatif
  • 179
  • 6
  • 15

4 Answers4

3

Use

s1.equals(s)

to compare strings, otherwise you compare references.

In second case it returns true because String s1 = "str" + "4"; would be optimized to String s1 = "str4"; and s and s1 would refer to the same String.

Nikolay Kuznetsov
  • 9,467
  • 12
  • 55
  • 101
  • Actually i don't need to compare the content of the object but i want to know how the 'references' are being changed on the heap memory. If equals() returns true it means the contents are same. But here my concern is only the reference. Thanks. – Aatif Mar 21 '13 at 06:58
  • @Aatif, so my answer already covers references part as well./ – Nikolay Kuznetsov Mar 21 '13 at 07:01
  • I'm still not clear with Case 1. How the references are different ?? – Aatif Mar 21 '13 at 07:11
  • @Aatif, two different objects would be created. It won't be optimized because of method call `s.length();` – Nikolay Kuznetsov Mar 21 '13 at 07:25
0

you need to use .equals() for this

.equals() // if you dont want to ignore case

.equalsIgnoreCase() // if you want to ignore case

== compare the references.

In the second case both strings are equal .So references are also equal.

   String s = "str4";
   String s1 = "str" + "4"; .//finally str4

Here s1 ans s2 contents are equal.So they have same reference.

PSR
  • 39,804
  • 41
  • 111
  • 151
  • 2nd case is pretty much clear for me because "str4" is already there and referenced by 's' and it's not created again on the heap but pointed to the variable 's1'. But how it's different from case 1. – Aatif Mar 21 '13 at 07:04
  • I'm still not clear with Case 1. How the references are different ?? – Aatif Mar 21 '13 at 07:09
  • @Aatif sorry i am unable to find the problem – PSR Mar 21 '13 at 07:12
  • It's ok. Let's see, someone will may answer and then the doubt will be cleared. – Aatif Mar 21 '13 at 07:14
  • @Aatif it is very interesting question.So +1 for u – PSR Mar 21 '13 at 07:14
0

The == operator in Java only returns true if both references refer to the same object. If you are trying to compare two Strings for equivalent content, you must use the equals() method.

jbruni
  • 1,238
  • 8
  • 12
  • I'm trying to check the reference only. But i'm not getting how the references are different in both cases. ? is it because of s.length() ?? – Aatif Mar 21 '13 at 07:05
0

In my own understanding :

"str" => String

"4" => String

However,

s.length() => int

With ==, memory locations are compared.

Using the first example, Java creates another String which is in another memory location other than the location of 's' because you are trying to do String + int = String.

The second example returns true because it is just the same memory location as your 's' only that the value is changed. String + String = Concatenated String

Since you are trying to compare if the two strings have the same characters inside but not necessarily the same location, then s.equals(s1) is the best solution.

However, should you want to test if both variables are pointing to the same object then == must be used because of its shallow comparison.

Community
  • 1
  • 1
Kim Honoridez
  • 917
  • 2
  • 15
  • 28
  • Thanks.! But before appending 'int' to String it is autoboxed to object if you are working with java 1.5 or above. I think that int 4 is also first getting autoboxed here... – Aatif Mar 21 '13 at 07:22