Varun
Varun

Reputation: 3321

Java .equals between String and StringBuilder

class returntest
{



public static void main(String...args)
{

String name1 = "Test";
String s = new String("Test");
StringBuilder sb = new StringBuilder("Test");

System.out.println(name1.equals(sb)); //Line 1
System.out.println(name1.equals(s));  //Line 2
System.out.println(s.equals(sb));     // Line 3
System.out.println(s.equals(name1));  //Line 4
}

}

The following is the output

false
true
false
true

Line 1 returns and Line 3 returns false.

I dont understand why compiler does not think "name1" and "sb" as containing the same value

Similarly compiler does not think "s" and "sb" as containing the same string (both are non-primitives).

Can someone explain the line1 and line3 output ?

Upvotes: 12

Views: 22560

Answers (12)

Saravana
Saravana

Reputation: 12817

Question Issue on Comparing String and Object value Java has been duplicated to this question so posting the answer here

Since String , StringBuffer and StringBuilder are implementing CharSequence you can check the content's equality by using contentEquals method in String

    "java".contentEquals(new StringBuffer("java")); // true
    "java".contentEquals(new StringBuilder("java")); // true

Upvotes: 2

dharam
dharam

Reputation: 8106

A simple answer would be, you do not compare apples and oranges. We being human know that these are same, the compiler is a program which cannot act as human intelligence.

It is the same reason as you cannot say that two objects one of which is a car and the other is the dis-assembled parts of the same car. Although both have same configuration :)

StringBuilder and String are completely different objects.

Upvotes: 0

Malwaregeek
Malwaregeek

Reputation: 2274

StringBuilder does not override the equals method.It inherit the equal method from Object class.Unless the references you are comparing to same objects, it will return false.

String overrides the equals method,so objects will return true if they are meaningfully equivalent.

Upvotes: 0

Stephen C
Stephen C

Reputation: 719336

The reason for the two false cases is that this is how the respective equals(Object) methods are specified to work.

  • For String.equals(Object), the javadoc says this:

    "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."

  • For StringBuilder.equals(Object), the equals method is inherited from Object, where the javadoc says this:

    "returns true if this object is the same as the obj argument; false otherwise."

So on Line #1 and Line #3, String.equals(Object) returns false because sb is not a String.

And if you reversed it and called sb.equals(name1) or sb.equals(s) you would get false also ... because sb.equals(...) is testing for the same object.


I dont understand why compiler does not think "name1" and "sb" as containing the same value

As you can see, it is nothing to do with the compiler ... and everything to do with the way that the equals method is specified.

Upvotes: 8

0decimal0
0decimal0

Reputation: 3984

I dont understand why compiler does not think "name1" and "sb" as containing the same value

Because the equals() checks the equality of references of objects and not their content , to use it to compare what these objects actually contain one needs to override the method itself. As you know string class also overrides this method.

Here ,

String name1 = "Test";
StringBuilder sb = new StringBuilder("Test");

name1 is a reference to the string "Test" which of String type and sb contains a reference to an object of StringBuilder type so they have an entirely different references. and thus equals returns false.

Now, why do the System.out.println(name1.equals(s)); prints true , because string literals can be interned and when you do String s = new String("Test"); the reference of the interned string object is used so they contain the same references.

As suggested by others you should therefore use sb.toString() instead of sb

Check out the Difference between object type and reference type to clear your concepts further.

Upvotes: 1

Suresh Atta
Suresh Atta

Reputation: 122006

Because they both are Different objects.

String object!= StringBuilder object.

But,Your doubt is

name1.equals(s)  returning true

Because in String class equals method ovverided in such a way.

And to get the desired output convert your StringBuilder to String.

System.out.println(s.equals(sb.toString())); //return true.

If you see the Source code of String#equals()

1012    public boolean  equals(Object anObject) {
1013        if (this == anObject) {
1014            return true;
1015        }
1016        if (anObject instanceof String) {             //key line 
1017            String anotherString = (String)anObject;
1018            int n = count;
1019            if (n == anotherString.count) {
1020                char v1[] = value;
1021                char v2[] = anotherString.value;
1022                int i = offset;
1023                int j = anotherString.offset;
1024                while (n-- != 0) {
1025                    if (v1[i++] != v2[j++])
1026                        return false;
1027                }
1028                return true;
1029            }
1030        }
1031        return false;
1032    }

The line if (anObject instanceof String) { always returns false incase if you pass StringBuilder.

Upvotes: 9

venky
venky

Reputation: 422

The 'name1' and 's' are objects of type "String". But "sb" is of type "StringBuilder".

Usually, equals() method would check for the reference and type. So , for above 2 and 4 statements it returns true as they both are of same.

But the StringBulider object "sb" and s, name1 are not same w.r.t type. So it returns false.

If you still want to get compare expecting true result, use sb.toString() and compare with above values(s, name1).

Upvotes: 0

Prabhaker A
Prabhaker A

Reputation: 8473

System.out.println(s.equals(sb));
You will get false since String class equals() method implemented so that passing null or other than String object gives false.

    public boolean equals(Object object){
          if(object instanceOf String){
             //do contnet comparison here
             //if both contents equal return true else fale
          }
          return false;
    }

Upvotes: 0

s.d
s.d

Reputation: 29436

String and StringBuilder are two different classes. equals() implementation checks type equality before checking the contents.

Upvotes: 0

bNd
bNd

Reputation: 7640

Use sb.toString() instead of direct sb directly.

This compares this string to the specified object.

        System.out.println(name1.equals(sb.toString())); //Line 1
        System.out.println(name1.equals(s));  //Line 2
        System.out.println(s.equals(sb.toString()));     // Line 3
        System.out.println(s.equals(name1));  //Line 4

This returns true value for all the line.

true
true
true
true

Upvotes: 2

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136082

String.equals compares not contents but objects

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        ...
    }
    return false;
}

StringBuilder does not override equals at all and inherits Object.equals

public boolean equals(Object obj) {
    return (this == obj);
}

Upvotes: 2

Moritz Petersen
Moritz Petersen

Reputation: 13057

.equals() checks if two objects are equal. This typically involves checking if both objects are of the same type.

If you only want to check if the values are equal, you should use sb.toString().

System.out.println(s.equals(sb.toString()));

Upvotes: 1

Related Questions