Java 对字符串使用compareto时,始终返回10

Java 对字符串使用compareto时,始终返回10,java,Java,相比之下,不要给我-10作为更大的理由。(当字符串与参数相等时,我得到0) 如果更改str2或str3的大小,则返回的编号相同。为什么会这样?在将字符串与compareTo进行比较时,唯一可以依赖的是,如果调用方法的字符串位于另一个字符串之前(根据字典顺序),则输出将为

相比之下,不要给我-10作为更大的理由。(当字符串与参数相等时,我得到0)


如果更改str2或str3的大小,则返回的编号相同。为什么会这样?

在将字符串与
compareTo
进行比较时,唯一可以依赖的是,如果调用方法的字符串位于另一个字符串之前(根据字典顺序),则输出将为<0;如果它位于另一个字符串之后,则输出将为0;如果它们相等,则输出将为0

从Javadoc:

int java.lang.String.compareTo(另一个字符串)

按字典顺序比较两个字符串。比较基于字符串中每个字符的Unicode值。此字符串对象表示的字符序列按字典顺序与参数字符串表示的字符序列进行比较如果此字符串对象按字典顺序位于参数字符串之前,则结果为负整数。如果此字符串对象按字典顺序跟随参数字符串,则结果为正整数。如果字符串相等,则结果为零;当equals(Object)方法将返回true时,compareTo将返回0

您不应该对该方法返回的实际值做任何假设,因为这是一个实现细节,在Java的任何未来版本中都可能发生变化

Java 8实现碰巧返回
c1-c2
,其中
c1
c2
是比较字符串的第一对对应字符,它们彼此不相等。如果一个字符串是另一个字符串的子字符串,则比较字符串的长度仅影响返回值

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;
}
public int compareTo(字符串另一个字符串){
int len1=value.length;
int len2=另一个string.value.length;
int lim=Math.min(len1,len2);
字符v1[]=值;
char v2[]=另一个string.value;
int k=0;
while(k

在您的示例中,比较的
字符串的第一个字符不同,因此
str2.compareTo(str3)
将首先返回
str2.charAt(0)-str3.charAt(0)
,而
str3.compareTo(str2)
将首先返回
str3.charAt(0)-str2.charAt(0)
<,您不应该试图以负、零、正以外的任何方式将返回值从
compareTo解释为
。价值的巨大回报没有任何意义

也就是说,OpenJDK中的
String.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;
}
public int compareTo(字符串另一个字符串){
int len1=value.length;
int len2=另一个string.value.length;
int lim=Math.min(len1,len2);
字符v1[]=值;
char v2[]=另一个string.value;
int k=0;
while(k
由于字符串按字母顺序进行比较,因此字符串的长度无关紧要-以I开头的字符串将位于以S开头的字符串之前,无论它们有多长

对于字符串,我们按字母顺序将字符串中的每个字符与另一个字符串中相同位置的字符进行比较,要在Java中做到这一点,我们可以使用一个简单的技巧


在Java中,我们可以对
char
s执行算术运算,要做到这一点,我们需要了解字符是如何真正表示的。您可以看到字符I,但计算机可以看到
73
——对于S,代码点是
83
。当
String.compareTo
看到SI不是同一个字符时,它返回
S-I
,这在码点算法中是
83-73
,这就是为什么如果切换字符串的顺序,会得到
10
(或者
-10

你的确切问题是什么?“如果更改str2或str3的大小,返回的数字是相同的”返回值与字符串的长度无关。提示:Unicode中
I
S
之间的距离为10个字符。(代码点73与代码点83)但正如Eran指出的那样,不要依赖于此。看看这个。我投票将这个问题作为离题题来结束,因为这是一个关于对标准函数的记录行为的误解的问题,而文档(似乎)没有被查阅。重复/相关:。
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;
}