1

I'm trying to see how to manually calculate the output when comparing strings as questions like it have come up in past papers I'm practicing.

I understand that the result is negative if the string lexicographically (according to unicode) precedes the argument string, positive if it follows it and zero if they are equal. I don't see how to calculate the value (beyond the sign).

I have the code which gives the output 1, -1, -3, 3. I see why each is positive or negative but not why it is 1 or 3.

public class CompareToPractice {
    public static void main(String[] args) {
        String str1 = "bode";
        String str2 = "bod";
        String str3 = "bodge";
        String str4 = "bog";

        int result1 = str1.compareTo(str2);
        System.out.println(result1);
        int result2 = str2.compareTo(str1);
        System.out.println(result2);
        int result3 = str3.compareTo(str4);
        System.out.println(result3);
        int result4 = str4.compareTo(str3);
        System.out.println(result4);
    }
}

Thank you

3
  • According to the contract, only the sign matters. If you're curious as to the actual implementation, just look at the source. Commented Apr 26, 2016 at 7:50
  • What do you mean by 'contract' shmosel? Commented Apr 26, 2016 at 9:00
  • the documentation of the Comparable interface. Commented Apr 26, 2016 at 16:05

3 Answers 3

5

Its the difference between the characters 'd' and 'e' (ascii difference).

This is the code of compareTo

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

As you can see from line if (c1 != c2). If 2 characters are not equal, then the result will be the subtraction of those 2 values.

In your case str3.compareTo(str4) was "bodge" - "bog".
So 'd'-'g' (ASCII value: 100 - 103 = -3)

Sign up to request clarification or add additional context in comments.

1 Comment

so it's the ascii value of the first two characters which don't match. I've just run the code to see but want to confirm that the result of "bodge" - "bog" was the same as "bod" vs "bog". They both give me -3. Thank you Bandi
2

I don't see how to calculate the value (beyond the sign).

The value "beyond the sign" is irrelevant. It conveys no information that a normal application could make use of1. It is a mere implementation detail: an accidental artifact of an algorithm that is optimized for speed.

If you really want to know, look at the source code.


1 - Well I suppose you could in theory construct a program that used it. But I can't conceive of a problem that such a program would solve ... apart from circular problems, such as investigating the statistical properties of compareTo!

3 Comments

In my question I said "questions like it have come up in past papers I'm practicing". There are several (10) questions each giving strings and "give the value of each expression". There's one mark per expression. I assume they're after a value, not just a sign. The things you have to do in exams often have nothing to do with real life :-)
Fine. But those exam questions don't ask you to explain the values for String.compareTo (without showing you the code) and explain what they "mean". In effect, that's what you asked in your Question. Instead, those exam questions ask you to work out what a >>given<< piece of code is going to do.
Thanks. But without understanding what the values will be, and how the code will do so, we can't answer the question. It's a pen and paper question; no IDE to use.
2

The documentation of compareTo clearly defines in what cases the result is calculated and how.

This is the definition of lexicographic ordering. If two strings are different, then either they have different characters at some index that is a valid index for both strings, or their lengths are different, or both. If they have different characters at one or more index positions, let k be the smallest such index; then the string whose character at position k has the smaller value, as determined by using the < operator, lexicographically precedes the other string. In this case, compareTo returns the difference of the two character values at position k in the two string -- that is, the value:

this.charAt(k)-anotherString.charAt(k)

If there is no index position at which they differ, then the shorter string lexicographically precedes the longer string. In this case, compareTo returns the difference of the lengths of the strings -- that is, the value:

this.length()-anotherString.length()

Also Bandi Kishore's answer explains the ASCII difference calculation: https://stackoverflow.com/a/36858565/904375

1 Comment

The documentation is difficult for me to understand whereas Bandi's answer really clarified it for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.