淘先锋技术网

首页 1 2 3 4 5 6 7

一、背景

1.集合的排序方法之前总结过,请参考我之前的博客:https://blog.csdn.net/chenmingxu438521/article/details/89785791

2.今天主要介绍的是String类中的compareTo()方法,主要从源码的角度去分析这个方法底层到底做了些什么,下面我们就开始吧。

二、源码解析compareTo(String str)

1.首先我们写一个str1.compareTo(str2),str1与str2的值我设置的是"i am a student",下面我们就开始跳进我们的源码,开始分析。

1.1.第一阶段的源码

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];
            //如果两个值相等的就返回的是0,比较的是字符的ascll码值
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        //如果两个值不相等的话,返回的是负数就是比较的值大,返回的是正值就是被比较的值大
        return len1 - len2;
    }

解析:如果两个值相等的就返回的是0,比较的是字符的ascll码值,如果返回的是正值或者是负值,比较的就是两个字符数组的长度之差。

三、源码解析compare(str1,str2)

1.首先我们写一个compareTo(str1,str2),str1与str2的值我设置的分别是"i am a student","i am a students",下面我们就开始跳进我们的源码,开始分析。

1.1.第一阶段的源码

public static final Comparator<String> CASE_INSENSITIVE_ORDER
                                         = new CaseInsensitiveComparator();
    private static class CaseInsensitiveComparator
            implements Comparator<String>, java.io.Serializable {
        // use serialVersionUID from JDK 1.2.2 for interoperability
        private static final long serialVersionUID = 8575799808933029326L;

        public int compare(String s1, String s2) {
            int n1 = s1.length();
            int n2 = s2.length();
            int min = Math.min(n1, n2);
            for (int i = 0; i < min; i++) {
                char c1 = s1.charAt(i);
                char c2 = s2.charAt(i);
                if (c1 != c2) {
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    if (c1 != c2) {
                        c1 = Character.toLowerCase(c1);
                        c2 = Character.toLowerCase(c2);
                        if (c1 != c2) {
                            // No overflow because of numeric promotion
                            return c1 - c2;
                        }
                    }
                }
            }
            return n1 - n2;
        }

解析:1.当是s1和s2分别为"i am a student","i am a students"的时候,这时候根据源码可以得出返回值是-1,是两个数组的长度之差,证明s2大。

           2.当是s1和s2分别为"i am a student","i am an student"的时候,这时候根据源码可以得出返回值是-78,证明s2大。这时候是两个字符的ascll码值之差。

           3.当是s1和s2分别为"i am a student","i am a student"的时候,这时候根据源码可以得出返回值是0,证明是s1,s2相等。这时候是两个数组的长度之差。

四、源码解析hashCode()方法

1.首先我们写一个hashCode(),str1的值我设置的是"java",下面我们就开始跳进我们的源码,开始分析。

1.1.第一阶段的源码

public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

解析:1.java每一个字符所对应的ascll码值分别为106、97、118、97

           2.第一次计算:31*0+106

           3.第二次计算:31*106+97

           4.第三次计算:31*3383+118

           5.第四次计算:31*104991+97

所以hash= 31*104991+97的值为3254818,即第四次的值

五、结束

有不对的地方请批评指正!!!