George_kane
George_kane

Reputation: 303

when using compareto for strings returns 10 all the time

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

Answers (2)

Raniz
Raniz

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

Eran
Eran

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

Related Questions