Reputation: 303
Compareto don't give me -10 for bigger argument. (when the string is equal with argument then i get 0).
String str2 = "Strings are immutable";
String str3 = "Int is a";
int result = str3.compareTo( str2 );
System.out.println(result);
result = str2.compareTo( str3 );
System.out.println(result);
if you change the size of str2 or str3 the return number is the same. why is that?
Upvotes: 2
Views: 1036
Reputation: 11113
First off, you shouldn't try to interpret the return value from compareTo
in any other way than negative, zero, positive. The greatness of the value returned carries no meaning.
That said, String.compareTo
in OpenJDK looks like this:
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
Since strings compare in alphabetical order the length of the strings doesn't matter - a string beginning with I will come before a string beginning with S regardless of how long they are.
In case of strings we compare each character in the string with the character in the same place in the other string alphabetically and to do this in Java we can use a simple trick.
In Java we can perform arithmetics on char
s and to do this we need to understand how characters are really represented. You see the character I but the computer sees the code point 73
- for S the code point is 83
. When String.compareTo
sees that S and I aren't the same character it returns S - I
which in code-point arithmetic is 83 - 73
and that's why you get 10
(or -10
if you switch the order of the strings.
Upvotes: 3
Reputation: 393936
The only thing you can rely on when comparing Strings with compareTo
is that the output would be < 0 if the String on which you call the method comes before the other String (according to lexicographical order), > 0 if it comes after the other String, and 0 if they are equal.
From the Javadoc:
int java.lang.String.compareTo(String anotherString)
Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argument string. The result is a negative integer if this String object lexicographically precedes the argument string. The result is a positive integer if this String object lexicographically follows the argument string. The result is zero if the strings are equal; compareTo returns 0 exactly when the equals(Object) method would return true.
You shouldn't make any assumptions regarding the actual value returned by that method, since that's an implementation detail, that can change in any future version of Java.
The Java 8 implementation happens to return c1 - c2
where c1
and c2
are the first pair of corresponding characters of the compared Strings not equal to each other. The lengths of the compared Strings only affect the returned value if one String is a sub-string of the other.
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
In your example the compared String
s differ in their first character, so str2.compareTo(str3)
will return str2.charAt(0)-str3.charAt(0)
, and str3.compareTo(str2)
will return str3.charAt(0)-str2.charAt(0)
.
Upvotes: 9