Java集合框架實現自定義排序


 Java集合框架針對不同的數據結構提供了多種排序的方法,雖然很多時候我們可以自己實現排序,比如數組等,但是靈活的使用JDK提供的排序方法,可以提高開發效率,而且通常JDK的實現要比自己造的輪子性能更優化。

一 、使用Arrays對數組進行排序

 Java API對Arrays類的說明是:此類包含用來操作數組(比如排序和搜索)的各種方法。

 1、使用Arrays排序:Arrays使用非常簡單,直接調用sort()即可

       int[] arr = new int[] {5,8,-2,0,10}; 

        Arrays.sort(arr); 

        for(int i=0;i<arr.length;i++){ 

            System.out.print(arr[i]+","); 

        } 

                 

        char[] charArr = new char[] {'b','a','c','d','D'}; 

        Arrays.sort(charArr); 

        for(int i=0;i<arr.length;i++){ 

            System.out.print(charArr[i]+","); 

        } 

如果需要降序排序, 升序排序后逆序即可:Collections.reverse(Arrays.asList(arr));

2、Arrays.sort()的實現

  查看源碼會發現,Arrays.sort()有許多重載的方法,如sort(int[] a)、sort(long[] a) 、sort(char[] a)等

public static void sort(int[] a) { 

       DualPivotQuicksort.sort(a); 

   } 

但最終都是調用了DualPivotQuicksort.sort(a)的方法,這是一個改進的快速排序,采用多路快速排序法,比單路快速排序法有更好的性能,  並且根據數組長度不同會最終選擇不同的排序實現,看一下這個方法的實現,這里不作展開:

public static void sort(char[] a) { 

        sort(a, 0, a.length - 1); 

    } 

     

 public static void sort(char[] a, int left, int right) { 

        // Use counting sort on large arrays 

        if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { 

            int[] count = new int[NUM_CHAR_VALUES]; 

 

            for (int i = left - 1; ++i <= right; 

                count[a[i]]++ 

            ); 

            for (int i = NUM_CHAR_VALUES, k = right + 1; k > left; ) { 

                while (count[--i] == 0); 

                char value = (char) i; 

                int s = count[i]; 

 

                do { 

                    a[--k] = value; 

                } while (--s > 0); 

            } 

        } else { // Use Dual-Pivot Quicksort on small arrays 

            doSort(a, left, right); 

        } 

    } 
 

private static void doSort(char[] a, int left, int right) { 

        // Use Quicksort on small arrays 

        if (right - left < QUICKSORT_THRESHOLD) { 

            sort(a, left, right, true); 

            return; 

        }    

二、使用Comparator或Comparable進行自定義排序

 集合框架中,Collections工具類支持兩種排序方法:

   Collections.sort(List<T> list); Collections.sort(List<T> list, Comparator<? super T> c)

 如果待排序的列表中是數字或者字符,可以直接使用Collections.sort(list);當需要排序的集合或數組不是單純的數字型時,需要自己定義排序規則,實現一個Comparator比較器。

下面了解一下Comparable和Comparator的應用。

   Comparable 是排序接口,一個類實現了Comparable接口,就意味着該類支持排序。

   Comparable 的定義如下:

public interface Comparable<T> { 

    public int compareTo(T o); 

}

接口中通過x.compareTo(y) 來比較x和y的大小。若返回負數,意味着x比y小;返回零,意味着x等於y;返回正數,意味着x大於y

當然這里的大於等於小於的意義是要根據我們的排序規則來理解的

Comparator是比較器接口,如果需要控制某個類的次序,而該類本身沒有實現Comparable接口,也就是不支持排序,那么可以建立一個類需要實現Comparator接口即可,在這個接口里制定具體的排序規則,
  Comparator接口的定義如下:

public interface Comparator<T> { 

    int compare(T o1, T o2); 

    boolean equals(Object obj); 

} 

 一個比較器類要實現Comparator接口一定要實現compareTo(T o1, T o2) 函數,如果沒有必要,可以不去重寫equals() 函數。因為在Object類中已經實現了equals(Object obj)函數方法。

   int compare(T o1, T o2)  和上面的x.compareTo(y)類似,定義排序規則后返回正數,零和負數分別代表大於,等於和小於。

三、如何對HashMap的key或者value排序

 HashMap作為kay-value結構,本身是無序的,排序比較靈活,一般會通過一個list進行保存。下面的代碼針對HashMap的key和value排序,提供幾種實現的思路:

1、轉換為key數組,按照key排序

Object[] key_arr = hashmap.keySet().toArray();    

Arrays.sort(key_arr);    

for  (Object key : key_arr) {     

    Object value = hashmap.get(key);     

}   

 2、對HashMap的value進行排序

public class HashMapSort { 

  public static void main(String[] args) { 

        HashMap<String, Integer> map = new HashMap<String, Integer>(){{ 

            put("tom", 18); 

            put("jack", 25); 

            put("susan", 20); 

            put("rose", 38); 

        }}; 

          

        ValueComparator cmptor = new ValueComparator(map);  

        /** 

         * 轉換為有序的TreeMap進行輸出 

         */ 

        TreeMap<String, Integer> sorted_map = new TreeMap<String, Integer>(cmptor); 

        sorted_map.putAll(map); 

          

        for(String sortedkey : sorted_map.keySet()){ 

            System.out.println(sortedkey+map.get(sortedkey)); 

        } 

        /** 

         * 轉換為有序的list進行排序 

         */ 

        List<String> keys = new ArrayList<String>(map.keySet()); 

        Collections.sort(keys, cmptor); 

        for(String key : keys) { 

             System.out.println(key+map.get(key)); 

        } 

    } 

    static class ValueComparator implements Comparator<String> { 

        HashMap<String, Integer> base_map; 

        public ValueComparator(HashMap<String, Integer> base_map) { 

            this.base_map = base_map; 

        } 

        public int compare(String arg0, String arg1) { 

            if (!base_map.containsKey(arg0) || !base_map.containsKey(arg1)) { 

                return 0; 

            } 

            //按照value從小到大排序 

            if (base_map.get(arg0) < base_map.get(arg1)) { 

                return -1; 

            } else if (base_map.get(arg0) == base_map.get(arg1)) { 

                return 0; 

            } else { 

                return 1; 

            } 

        } 

    } 

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM