Reputation: 36304
I have the following code
public static void main(String... args) {
String s = "abc";
System.out.println(s.hashCode());
String s1 = " abc ";
System.out.println(s1.hashCode());
String s2 = s.trim();
System.out.println(s2.hashCode());
String s3 = s1.trim();
System.out.println(s3.hashCode());
System.out.println();
System.out.println(s == s1);
System.out.println(s == s2);
System.out.println(s == s3);
}
OP:
96354
32539678
96354
96354
false -- Correct
true -- This means s and s2 are references to the same String object "abc" .
false -- s3=s1.trim()... which means s3="abc" yet s==s3 fails.. If the above conditon were to be considered (s==s2 is true..) , this should also be true..
Why am i getting "false" when i check s==s3 ?..
Upvotes: 5
Views: 275
Reputation: 139
The Java 7 source code for java.lang.String.trim() (from the installed JDK) is:
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
The return statement states that if there is no change to the String being trimmed, then this is returned, hence s == s2:
String s = "abc";
String s2 = s.trim();
System.out.println(s == s2); // is true
When the String being trimmed needs to be trimmed, java.lang.String.substring() is called. The source code for substring() in Java 7 is:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}
When the String being trimmed has to be trimmed, then substring() returns a new String:
new String(value, beginIndex, subLen)
This is why s != s3:
String s = "abc";
String s1 = " abc ";
String s3 = s1.trim();
System.out.println(s == s3); // is false
Source code for this answer is available on GitHub here.
Upvotes: 1
Reputation: 6774
see in documentation - http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#trim() -
A copy of this string with leading and trailing white space removed, or this string if it has no leading or trailing white space.
when the string is staying the same it returns the string given itself.
Upvotes: 1
Reputation: 2895
becuase s1.trim()
will return a new instance. Strings are immutable so every time a function applied on Strings then a new instance will be returned and You are using ==
which compares the instance equality
Edit: As suggested By Chris Hayes and R.J.
trim
is smart and returns this
if there's no whitespace to trim. So in second case you have ' abc ' white spaces so in this case it is not returning this
but a new instance of string.
source code of trim method
Upvotes: 5
Reputation: 11775
If you take a look at String.trim
you'll see that it eventually calls String.substring
which in turn returns new String(...)
if the string is getting actually trimmed. That's why ==
fails.
Upvotes: 2
Reputation: 68945
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
As you can see in your case(System.out.println(s == s2);
) this
is returned which is pointing to same reference which is why you get true.
Upvotes: 2