目录
1. 缘起:
技术群一个小伙伴发图片提问题,截图如下(请忽略群里吹水的内容,打了马赛克还是看的见),运行的结果可能不符合他的预期,不清楚怎么回事。
代码呢如下,我给单独整出来,就两行,不多。当时直接答复让提问的同学先看看源码,话说这个方法以前博主也没留意过,不清楚的东西不进行盲目推测。
package com.xasnow;
public class CompareToTest {
public static void main(String[] args) {
System.out.println("2000".compareTo("50") > 0 ? true : false); //false
System.out.println("2000".compareTo("1000") > 0 ? true : false);//true
}
}
2.源码分析:
/**
* Compares two strings lexicographically.
* The comparison is based on the Unicode value of each character in
* the strings. The character sequence represented by this
* {@code String} object is compared lexicographically to the
* character sequence represented by the argument string. The result is
* a negative integer if this {@code String} object
* lexicographically precedes the argument string. The result is a
* positive integer if this {@code String} object lexicographically
* follows the argument string. The result is zero if the strings
* are equal; {@code compareTo} returns {@code 0} exactly when
* the {@link #equals(Object)} method would return {@code true}.
* <p>
* 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 <i>k</i> be the smallest such index; then the string
* whose character at position <i>k</i> has the smaller value, as
* determined by using the < operator, lexicographically precedes the
* other string. In this case, {@code compareTo} returns the
* difference of the two character values at position {@code k} in
* the two string -- that is, the value:
* <blockquote><pre>
* this.charAt(k)-anotherString.charAt(k)
* </pre></blockquote>
* If there is no index position at which they differ, then the shorter
* string lexicographically precedes the longer string. In this case,
* {@code compareTo} returns the difference of the lengths of the
* strings -- that is, the value:
* <blockquote><pre>
* this.length()-anotherString.length()
* </pre></blockquote>
*
* @param anotherString the {@code String} to be compared.
* @return the value {@code 0} if the argument string is equal to
* this string; a value less than {@code 0} if this string
* is lexicographically less than the string argument; and a
* value greater than {@code 0} if this string is
* lexicographically greater than the string argument.
*/
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;
}
很明显这个方法属于Java基础String类的,源码就这几行,其实方法上方的注释已经对该方法的含义进行了说明,可能英语不好同学看起来比较费事,那咱就看看代码。
- 先获取了需要比较的两个字符串的长度,获取最小长度lim;
- 然后将两个字符串的值,分别赋值给char类型数组,v1[],v2[];
- 重点来了,在While里面比较两个char类型同位置的元素ASCII码int值的大小,从首位开始比较,当c1!= c2时,两值相减,直接return 结果;
再回到代码:
System.out.println("2000".compareTo("50") > 0 ? true : false); //false
实际结果是将“2000”首位的2与“50”首位的5进行比较,2-5 < 0 ,所以返回false。
另外一种情况同理,就不过多介绍了。
3. 结语:
开发人员对一些API的结果存在疑问时,养成看源码的习惯,代码本身已经告诉了它要做的一切,再说很多方法还有英文注释,现在翻译工具这么方便,英语不好了借用工具翻译也能弄清方法的功能,最后通过写一些小的test来验证自己的理解。