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; 

            } 

        } 

    } 

}
时间: 2024-12-24 22:20:35

Java集合框架实现自定义排序的相关文章

java集合框架22

思想:在面向对象的思想里,一种数据结构被认为是一种容器.在本质上来讲是一个类,提供方法支持查找,插入和删除等等操作. Java集合框架支持以下俩种类型的容器: 存储一个元素集合,简称为集合Collection 存储键值对,称为图Map 集合collection 三种主要类型 : 规则集(set) , 线型表(List) , 队列(Queue) set: 存储一组不重复的数据 List: 存储由元素构成的有序集合 Queue: 存储先进先出方式处理的对象 细说Collection接口: 它是处理对

Java集合框架总结(5)——Map接口的使用

Java集合框架总结(5)--Map接口的使用 Map用于保存具有映射关系的数据(key-vlaue).Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回false Map中包含了一个keySet()方法,用于返回Map所以key组成的Set集合. Map集合与Set集合元素的存储形式很像,如Set接口下有HashSet.LinkedHashSet.SortedSet(接口).TreeSet.EnumSet等实现类和子接口,而Map接口下则有HashMa

[转载]Java集合框架的常见面试题

http://www.jfox.info/40-ge-java-ji-he-lei-mian-shi-ti-he-da-an 整理自上面链接: Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点.这里,我列出了一些关于Java集合的重要问题和答案. 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用, Java1.2提出了囊括所有集

黑马程序员——JAVA集合框架学习总结

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- www.itheima.com 要学好java的集合框架,必须掌握此图: Java集合框架很全面,从大的来说.它包括两种类型: 1.一种是以collection为根接口的集合. 2.另一种是由map为根接口的<key,value>的“图”. 而collection之下的set接口和list接口又有不同: 1.Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制.

java集合框架小结(初级版)

今天大概的整理了一下java集合框架,在这里做一个小结,方便以后查阅,本博文主要参考资料为<java编程思想第四版>第11章——持有对象以及JAVA 1.6 API文档.并没有研究更深入的第17章<容器深入研究>.大概介绍了集合框架中几个比较常用的集合类. 以下为正文. 首先来看一张图,不太会用visio,画的可能不太好看 图中将接口.抽象类.实现类.淘汰类(圆角矩形)进行标注.有直线连接的类(或接口)表示是子类关系或者实现关系 由图示可以看出,集合类主要有两个集合接口: 1.Co

Java集合框架中隐藏的设计套路

我们的世界不应该只有"胡萝卜" 进入正题之前容我先扯点别的. 最近突然想到了一个驴子和胡萝卜不得不说的故事.说是一个人坐在驴子背上,用一根长杆绑着一根胡萝卜,然后把胡萝卜悬到驴子的面前,驴子以为只要向前走一步就可以吃到胡萝卜,于是不停地向前走,可是它始终无法吃到这根萝卜. 一千个读者就有一千个哈姆雷特,当然不同的人对这个故事也会有不同的理解.比如我们为了生活拼命地工作,却永远达不到财务自由,我们是不是也像一只忙碌的"驴子"呢? 所以,我们的世界不应该只有"

【JAVA集合框架之工具类】

一.概述 JAVA集合框架中有两个很重要的工具类,一个是Collections,另一个是Arrays.分别封装了对集合的操作方法和对数组的操作方法,这些操作方法使得程序员的开发更加高效. public class Collections extends Object 全类名:java.util.Collections public class Arrays extends Object 全类名:java.util.Arrays 二.Collections类. 1.Collections.sort

Java集合框架梳理(含经典面试题)

Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含一组接口,类的体系结构. 1. 整体框架 Java容器类库一共有两种主要类型:Collection和Map.层次结构如下: 蓝色椭圆框为接口类(不可实例化),黑色矩形框为实现类或子类. java.util.Collection [I] +--java.util.List [I] +--java.util.ArrayList [C] +--java.util.LinkedList [C] +--j

异常处理、常用类、Java集合框架、反射

异常处理: 1.  异常:程序在执行过程中所产生的问题. 异常的三种类:①检查异常:又叫checdked异常或者受检异常.通常是用户错误或者不能被程序员所预见的问题.检查异常需要被解决之后才能通过编译. ②运行时异常:程序在运行过程中可能发生的.可以被程序员所避免的异常类型. ③错误:事实上错误不是异常,但却是用户和程序员无法控制的问题. 2.  异常的控制流程: 异常是被一个方法抛出的对象. (1) 处理异常的三个方法:①捕获这个异常,不让它沿着调用栈继续向下抛. ②捕获这个异常,并继续向下抛