Java源码解析之compareTo()方法

一. 前言

​ 近日研究了一下String类的一些方法, 通过查看源码, 对一些常用的方法也有了更透彻的认识, 也让我更加理解了设计者的算法思想.

​ 我也推荐大家多读读源码, 相信大家也会有意想不到的收获.

二. 实战

​ 今天我分析的是String类的compareTo(String otherString)方法.

  以下是我个人的分析观点, 如有哪里分析不到位的地方, 欢迎大家指出, 相互学习, 共同进步 !

  首先, 尊重原作者, 先放上源码.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
}

下面的是我自己写的山寨compareTo()方法, 经测试, 结果与compareTo(String otherString)返回一致

说明:

   1. 为避免冲突, 我定义的方法名为compares

  1. 注释中已经详细地记录了分析思路, 故对代码不做过多说明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    public class StringDemo {

    @Test
    public void test() {

    // 因为o的ASCII码为: 111
    // 因为a的ASCII码为: 97
    // 所以差为 : 111 - 97 = 14
    // 返回值为:14, 与compareTo返回结果一致
    System.out.println(compares("hellojava", "hellajava"));
    }

    public static int compares(String firstString, String lastString) {
    /*
    * 算法思路分析:
    * 1. 获取2个字符串, 首先把2个字符串都转化为字符数组 (为后面一个一个字符进行比较做铺垫)
    * 2. 获取2个字符串的长度, 并把最短的字符串长度作为循环的次数 (这样可以避免数组越界异常)
    * 3. 把2个字符串从0开始遍历, 比较每一个字符, 若字符不相等时, 则返回两个字符串的差值
    * 4. 如果遍历的字符串都相等时, 则返回两个字符串的长度差
    *
    * 方法结果:
    * 1. 若两个字符串长度和字符都相等时, 则返回0
    * 2. 若两个字符长度不相等, 但大串完全包含(顺序和字符都相等)小串字符时, 则返回两个字符串的长度的差值
    * 举例:
    * 大串: helloworlds
    * 小串: helloworld
    * 因为大串完全包含小串, 所以返回长度的差值, 为1
    * 3. 若两个字符串长度和字符都不相等时, 则返回比较过程中, 某个索引位置上的字符之差
    * 举例:
    * 串1: hellojavas
    * 串2: hellajava
    * 遍历比较后, 索引4的字符不同, 所以返回两个字符的差值14, 'o' - 'a' = 14
    */

    /*
    * 1. 获取2个字符串, 首先把2个字符串都转化为字符数组 (为后面一个一个字符进行比较做铺垫)
    */
    char[] firstCh = firstString.toCharArray();
    char[] lastCh = lastString.toCharArray();

    /*
    * 2. 获取2个字符串的长度, 并把最短的字符串长度作为循环的次数 (这样可以避免数组越界的异常)
    */
    int firstLength = firstCh.length;
    int lastLength = lastCh.length;
    int lim = Math.min(firstLength, lastLength);

    // 用k记录比较的索引
    int k = 0;
    while(k < lim) {
    char c1 = firstCh[k];
    char c2 = lastCh[k];

    // 3. 把2个字符串从0开始遍历, 比较每一个字符, 若字符不相等时, 则返回两个字符串的差值
    if(c1 != c2) {
    return c1 - c2;
    }

    // 如果字符相等, 则让索引加1
    k++;
    }

    // 4. 如果遍历的字符串都相等时, 则返回两个字符串的长度差
    return firstLength - lastLength;
    }
    }
0%