zoukankan      html  css  js  c++  java
  • 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; 
    
                } 
    
            } 
    
        } 
    
    }
    
  • 相关阅读:
    备忘
    基于ZooKeeper实现分布式锁
    git 使用ssh密钥
    git 的安装及使用
    sqlalchemy 使用pymysql连接mysql 1366错误
    SQL语句及5.7.2 mysql 用户管理
    C 实现快速排序
    C 实现冒泡排序
    C 实现选择排序
    sqlalchemy orm 操作 MySQL
  • 原文地址:https://www.cnblogs.com/moonandstar08/p/5686545.html
Copyright © 2011-2022 走看看