Java集合框架实现自定义排序

Java集合框架针对不同的数据结构提供了多种排序的方法,
虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优化。

1.使用Arrays对数组进行排序

Java API对Arrays类的说明是:此类包含用来操作数组(比如排序和搜索)的各种方法。

(1)使用Arrays排序

Arrays使用非常简单,直接调用sort()即可:


1

2

3

4

5

6

7

8

9

10

11

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]+",");

        }

如果需要降序排序, 升序排序后逆序即可:


1

Collections.reverse(Arrays.asList(arr)); 

(2)Arrays.sort()的实现

查看源码会发现,Arrays.sort()有许多重载的方法,如sort(int[] a)、sort(long[] a) 、sort(char[] a)等,


1

2

3

public static void sort(int[] a) {

       DualPivotQuicksort.sort(a);

   }

但最终都是调用了DualPivotQuicksort.sort(a)的方法,

这是一个改进的快速排序,采用多路快速排序法,比单路快速排序法有更好的性能,
并且根据数组长度不同会最终选择不同的排序实现,

看一下这个方法的实现,这里不作展开:  


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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);

        }

    }

  


1

2

3

4

5

6

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;

        }  

2.使用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 的定义如下:


1

2

3

public interface Comparable<T> {

    public int compareTo(T o);

}

接口中通过x.compareTo(y) 来比较x和y的大小。若返回负数,意味着x比y小;返回零,意味着x等于y;返回正数,意味着x大于y

当然这里的大于等于小于的意义是要根据我们的排序规则来理解的

Comparator是比较器接口,如果需要控制某个类的次序,而该类本身没有实现Comparable接口,也就是不支持排序,那么可以建立一个类需要实现Comparator接口即可,在这个接口里制定具体的排序规则,
Comparator接口的定义如下:


1

2

3

4

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)类似,定义排序规则后返回正数,零和负数分别代表大于,等于和小于。

 

3.如何对HashMap的key或者value排序

HashMap作为kay-value结构,本身是无序的,排序比较灵活,一般会通过一个list进行保存。

下面的代码针对HashMap的key和value排序,提供几种实现的思路:

(1)转换为key数组,按照key排序


1

2

3

4

5

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

Arrays.sort(key_arr);    

for  (Object key : key_arr) {    

    Object value = hashmap.get(key);    

}  

(2)对HashMap的value进行排序


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

/**

 * 针对HashMap的value进行排序

 * @author Bingyue

 */

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;

            }

        }

    }

}

输出:

tom18     
susan20   
jack25    
rose38   
tom18   
susan20  
jack25    
rose38    

4.通过Comparator自定义实体排序

如果你的List包装的是基本类型或者String,只要Collections.sort(list)即可,
但是如果list中保存的是实体bean等,就需要自己定义排序规则。

Java可以对ArrayList中的对象按照该对象某属性排序,下面的操作实现对Person实体列表的排序:

(1)定义Person实体类


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

public class Person{

     String name;

     int age;

 public Person(String name,int age){

     this.name = name;

     this.age = age; 

 }

 

 public int getAge() {

     return age;

 }

 public void setAge(int age) {

     this.age = age;

 }

 public String getName() {

     return name;

 }

 public void setName(String name) {

     this.name = name;

 }

} 

(2)实现Comparator接口,编写排序规则


1

2

3

4

5

6

7

8

9

10

public class Mycomparator implements Comparator{<br>// 实现Comparator接口,也就是定义排序规则

    public int compare(Object o1,Object o2) {

        Person p1=(Person)o1;

        Person p2=(Person)o2;

       if(p1.age<p2.age)

           return 1;

       else

           return 0;

       }

} 

(3)测试排序


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public class ListSort {

     public static void main(String[] args){

         ArrayList list = new ArrayList();

         list.add(new Person("lcl",28));

         list.add(new Person("fx",23));

         list.add(new Person("wqx",29));

         Comparator comp = new Mycomparator();

         Collections.sort(list,comp);

         for(int i = 0;i<list.size();i++){

             Person p = (Person)list.get(i);

             System.out.println(p.getName());

         }

    

     }

  

}

  

时间: 2024-10-20 23:02:14

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

关于Java集合框架面试题(含答案)下_java

21.HashMap和HashTable有何不同? (1)HashMap允许key和value为null,而HashTable不允许. (2)HashTable是同步的,而HashMap不是.所以HashMap适合单线程环境,HashTable适合多线程环境. (3)在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的. (4)HashMap

Java集合框架List,Map,Set等全面介绍

Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含一组接口,类的体系结构.   Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +--java.util.LinkedList [C]   +--java.util.Vector [C]      +--java.util.Stack [C]+--ja

java | 集合框架

集合框架 集合代表了一组对象,Java中的集合框架定义了一套规范,用来表示.操作集合,使具体操作与实现细节解耦. 而这些操作无非就是增.删.改.查! 集合和数组的区别: 1.数组的长度固定,集合长度可变. 2.数组只能存储相同类型的数据(基本类型/引用类型),集合可存储各种类型的数据. Java集合框架接口 Java集合框架的顶层接口包括: 一.Collection接口: 1.实现Collection接口的集合有List.Set.Queue(Java队列实现). 2.List:排列有序,可以有重

[Java] 集合框架的层次结构和使用规则梳理

在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(JavaCollectionFramework). Java程序员在具体应用时,不必考虑数据结构和算法实现细节,只需要用这些类创建出来一些对象,然后直接应用就可以了,这样就大大提高了编程效率. 概述 什么是框架?  类库的集合 什么是集合? 存放数据的容器 集合框架用来干什么? 用来表示和操作的统一的架构 集合框架包含了两部分:一

Java集合框架学习总结

<Java集合框架学习总结> 以下介绍经常使用的集合类,这里不介绍集合类的使用方法,只介绍每个集合类的用途和特点,然后通过比较相关集合类的不同特点来让我们更深入的了解它们.   Collection接口 1.Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements). 2.所有实现Collection接口的类都必须提供两个标准的构造函数:1.无参数的构造函数用于创建一个空的Collection,2.Collection

JAVA集合框架之Set接口实现类

在上一篇<JAVA集合框架>中为大家介绍了JAVA集合框架的基本组成,这一片开始将为大家介绍集合框架中常用的实现类的用法. java.util.HashSet< E > 此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持.它不保证 set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用 null 元素.这是我们最常用的Set接口的实现类. 构造方法 方法名 说明 HashSet() 构造一个新的空 set,其底层 HashMap 实例的默认初始容量是

Java集合框架:HashMap

Java集合框架概述   Java集合框架无论是在工作.学习.面试中都会经常涉及到,相信各位也并不陌生,其强大也不用多说,博主最近翻阅java集合框架的源码以及搜索一些相关资料整理出Java集合框架的系列.一方面是做一个总结,方便以后查阅,另一方面希望各位小伙伴能够提出不足之处,我会及时更新修改.   博主从网上抠了一张图,觉得画得还是比较形象的,给大家参考一下.   上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如Abst

java集合框架10——TreeMap和源码分析(一)

版权声明:尊重博主原创文章,转载请注明出处哦~http://blog.csdn.net/eson_15/article/details/51217741 目录(?)[+] 前面讨论完了HashMap和HashTable的源码,这一节我们来讨论一下TreeMap.先从整体上把握TreeMap,然后分析其源码,深入剖析TreeMap的实现. 1. TreeMap简介         TreeMap是一个有序的key-value集合,它内部是通过红-黑树实现的,如果对红-黑树不太了解,请先参考下这篇博

详谈java集合框架_java

1.为什么使用集合框架 当我们并不知道程序运行时会需要多少对象,或者需要更复杂方式存储对象--可以使用Java集合框架 2.Java集合框架包含的内容 接口:(父类)Collection接口下包含List(子类 )接口和Set(子类) 接口 List接口下又包含(ArrayList集合实现类和LinkedList集合实现类) Set接口下又包含(HashSet集合实现类和TreeSet集合实现类) 接口:(父类)Map接口下包含(HashMap集合实现类和TreeMap 集合实现类) *Coll