比较不要给我-10更大的论点。 (当字符串与参数相等时,我得到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);
如果更改str2或str3的大小,则返回编号相同。那是为什么?
答案 0 :(得分:8)
将字符串与compareTo
进行比较时,唯一可以依赖的是输出将是<如果您调用方法的String位于另一个String之前(根据词典顺序),则为0;如果它在另一个String之后,则为0;如果它们相等,则为0。
来自Javadoc:
int java.lang.String.compareTo(String anotherString)
按字典顺序比较两个字符串。比较基于字符串中每个字符的Unicode值。此String对象表示的字符序列按字典顺序与参数字符串表示的字符序列进行比较。 如果此String对象按字典顺序排在参数字符串之前,则结果为负整数。如果此String对象按字典顺序跟随参数字符串,则结果为正整数。如果字符串相等则结果为零; compareTall在equals(Object)方法返回true时完全返回0。
您不应该对该方法返回的实际值做任何假设,因为这是一个实现细节,可以在任何未来版本的Java中更改。
Java 8实现恰好返回c1 - c2
,其中c1
和c2
是比较字符串的第一对相应字符,彼此不相等。如果一个String是另一个字符串的子字符串,则比较的字符串的长度仅影响返回的值。
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;
}
在您的示例中,比较String
的第一个字符不同,因此str2.compareTo(str3)
将返回str2.charAt(0)-str3.charAt(0)
,str3.compareTo(str2)
将返回str3.charAt(0)-str2.charAt(0)
。
答案 1 :(得分:3)
首先,您不应尝试以除否定,零,正面<之外的任何其他方式解释compareTo
的返回值/ em>的。返回值的伟大意义没有任何意义。
那就是说,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;
}
由于字符串按字母顺序进行比较,字符串的长度无关紧要 - 以 I 开头的字符串将出现在以 S 开头的字符串之前,无论多长时间他们是。
在字符串的情况下,我们将字符串中的每个字符与另一个字符串中相同位置的字符按字母顺序进行比较,并且在Java中我们可以使用一个简单的技巧。
在Java中,我们可以在char
上执行算术运算,为此,我们需要了解字符的真实表示方式。您会看到字符我,但计算机会看到code point 73
- S 代码点为83
。当String.compareTo
看到 S 且 I 不是同一个字符时,它会返回S - I
,这在代码点算术中为83 - 73
这就是为什么你得到10
(或-10
,如果你改变字符串的顺序。