字符串数组的排序(三)

一 字符串数组的排序


常见的排序是数字型数组的排序,有冒泡法,快速排序法,插入法等。 字符串数组也可以进行相应的排序,只是字符串之间的比较并不是通过 > < 来进行体现的。 字符串提供了一个方法,叫做 compareTo() 的方法,是利用字典顺序进行相应的比较。这里,字符串数组的排序所用的方法是 简单的冒泡排序法。


二. compareTo() 方法的使用比较


字符,数字 之间的比较


@Test
    public void testA(){
        System.out.println("abc".compareTo("acd")); //返回-1  b小于c,前面的小于后面的
        
        System.out.println("abc".compareTo("aef"));  //返回-3  b小于e,中间相差3个值,e-b=3
        
        System.out.println("acd".compareTo("abc")); //1 c大于b
        
        System.out.println("aef".compareTo("abc")); //3 
        
        System.out.println("acd".compareTo("123")); // 48  为97-49=48 字符串大于数字
        
        System.out.println("123".compareTo("acd")); // -48 
        System.out.println("acd".compareTo("acd1234")); // -4 返回的是相差的长度 
    }


实际上,比较的是ASCII 码的大小,返回的值也是最近那两个字符不同的差值,如果相同返回0. 但返回值并不是以前常见的 -1, 1, 0.


三. 源代码的分析


public int compareTo(String anotherString) {
        // 当前字符串的长度
        int len1 = value.length;
        // 要比较的字符串的长度
        int len2 = anotherString.value.length;
        // 求出最小的字符串的长度
        int lim = Math.min(len1, len2);
        // 当前字符串转换成字符数组,相当于 toCharArray();
        char v1[] = value;
        // 要比较的字符串转换成字符数组
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) { //用while 循环
            // 当前的字符串的那个字符值
            char c1 = v1[k];
            // 要比较的字符串的那个字符值
            char c2 = v2[k];
            // 不同时,返回 ASCII 码的差值。
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        // 前面的全部相同,那么则返回两个字符串的长度的差值。
        // 全部相同,用的也是len1-len2,即全部相同时,长度也一定相同,返回长度差值0.
        return len1 - len2;
    }


String 中还有一个 CaseInsensitiveComparator 的比较器,


 public static final Comparator<String> CASE_INSENSITIVE_ORDER
                                         = new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
            implements Comparator<String>, java.io.Serializable {
  }


但是这个比较器,只是用来比较忽略大小写的。 即比较时,忽略大小写。


 public int compareToIgnoreCase(String str) {
        return CASE_INSENSITIVE_ORDER.compare(this, str);
    }


所调用的compare() 方法是:


 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++) {
            //得到i 索引的值
                char c1 = s1.charAt(i);
                char c2 = s2.charAt(i);
                //看两个字符的ASCII 码是否相同
                if (c1 != c2) {
                    // 不相同,转换成大写字符
                    c1 = Character.toUpperCase(c1);
                    c2 = Character.toUpperCase(c2);
                    // 如果大写字符不相同,就转换成小写字符
                    if (c1 != c2) {
                        c1 = Character.toLowerCase(c1);
                        c2 = Character.toLowerCase(c2);
                        // 小写字符不相同,就返回小写字符的ASCII 码。
                        if (c1 != c2) {
                            // No overflow because of numeric promotion
                            return c1 - c2;
                        }
                    }
                }
            }
            // 返回长度的差值。
            return n1 - n2;
        }


这样的写法,感觉有点多余,直接都转换成大写,进行判断不行吗? 为什么要转换成大写之后,再转换成小写呢? 感觉没有 compareTo () 方法写得简单。 也许,底层人员是提示不同的解决方法吧。 注意,忽略大小写的比较,是用的一个比较器,并不是单纯的对字符串的处理后比较。


测试:


@Test
    public void testB(){
        System.out.println("abc".compareToIgnoreCase("ABC"));  //0 
        System.out.println("abc".compareToIgnoreCase("Abc"));  //0 
        System.out.println("abc".compareToIgnoreCase("AbC"));  //0 
    
    }


四. 字符串数组排序


public static void main(String []args){
        String[] arr=new String[]{"abc","aed","afg","cdeg","acd"};
        System.out.println("排序前:");
        print(arr);
        compareArr(arr);
        System.out.println("排序后:");
        print(arr);
    }
private static void compareArr(String[] arr) {
        //利用冒泡排序法进行相关的排序
        for (int i = 0; i < arr.length; i++) {
            for(int j=0;j<arr.length-1-i;j++){
                // 比较方式是> 0 <0 这样的比较。
                if(arr[j].compareTo(arr[j+1])>0){
                    // 数组元素间进行调换
                    swapArr(arr,j,j+1);
                }
            }
        }
    }
    // 调换数组元素的值
    private static void swapArr(String []arr,int start,int end){
        String temp=arr[start];
        arr[start]=arr[end];
        arr[end]=temp;
    }
    // 打印输出数组
    private static void print(String []arr){
        System.out.println(Arrays.toString(arr));
    }


字符串数组的排序(三)


谢谢!!!


上一篇:C调用Python崩溃的记录


下一篇:第八章:手把手教老婆实现:RocketMQ集群模式(1)-介绍