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 } } 

Below is the conclusion

 false true false true 

Line 1 is returned, and line 3 returns false.

I do not understand why the compiler does not think that "name1" and "sb" contain the same value

Similarly, the compiler does not consider "s" and "sb" to contain the same string (both are non-primitives).

Can someone explain the output of line1 and line3?

+4
source share
12 answers

Because they are both different objects .

 String object!= StringBuilder object. 

But, your doubt is

 name1.equals(s) returning true 

Because in the String class, the method is ovverided this way.

And to get the desired result, convert your StringBuilder to String .

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

If you see Source Code 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 } 

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

+6
source

The reason for the two cases of false is that the corresponding equals(Object) methods work this way.

  • In String.equals(Object) javadoc says the following:

    "Compares this string with 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 inherits from Object , where javadoc says the following:

    "returns true if this object matches the argument obj, otherwise false."

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

And if you cancel it and call sb.equals(name1) or sb.equals(s) , you will also get false ... because sb.equals(...) testing the same object.


I do not understand why the compiler does not think that "name1" and "sb" contain the same value

As you can see, this has nothing to do with the compiler ... and all that has to do with the way the equals method is specified.

+6
source

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

This compares this string with 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 for the entire string.

 true true true true 
+2
source

String.equals compares objects, not contents

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

StringBuilder does not override values ​​at all and inherits from Object.equals

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

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

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

 System.out.println(s.equals(sb.toString())); 
+1
source
 I dont understand why compiler does not think "name1" and "sb" as containing the same value 

Since equals() checks the equality of object references, not their contents, to use it to compare what these objects actually contain, you must redefine the method itself . As you know, the 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 type String and sb contains a reference to an object of type StringBuilder, so they have completely different links. and thus equals returns false.

Now why 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 to the interned string object is used, therefore they contain the same links.

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

Note the Difference between the type of the object and the type of the link to further refine your concepts.

+1
source

String and StringBuilder are two different classes. equals() implementation checks for type matching before checking for content.

0
source

System.out.println(s.equals(sb));
You will be mistaken The String class equals() method is implemented so that passing null or another 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; } 
0
source

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

Normally, the equals () method will check the link and type. Thus, for over 2 and 4 operators, it returns true, since both are the same.

But the StringBulider object "sb" and s, name1 are not the same type as wrt. So it returns false.

If you still want a comparison that expects a true result, use sb.toString () and compare with the values ​​above (s, name1).

0
source

The simple answer is that you are not comparing apples and oranges. We humans know that they are the same; a compiler is a program that cannot act like a human mind.

This is the same reason you cannot say that two objects, one of which is a car, and the other are unsorted parts of the same car. Although both have the same configuration :)

StringBuilder and String are completely different objects.

0
source

StringBuilder does not override the equals.It method, it inherits an equal method from the Object class. Despite the references that you compare with the same objects, it will return false.

String overrides the equals method, so objects return true if they make sense.

0
source

Question The issue with matching String and Object Java values was duplicated in this question, so post your answer here

Since String , StringBuffer and StringBuilder implement CharSequence , you can check for equality of content using the contentEquals method in String

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

Source: https://habr.com/ru/post/1499896/


All Articles