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

1.使用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;
}

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 的定义如下:

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

3.如何对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进行排序

/**
* 针对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实体类

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接口,编写排序规则

public class Mycomparator implements Comparator{
// 实现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)测试排序

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

  

参考 

java中HashMap,LinkedHashMap,TreeMap,HashTable的区别

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

  1. Java集合框架和数组的排序(转载)

    Java集合框架(*Collection)*和数组的排序 ​ 根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还 ...

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

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  3. 【集合框架】Java集合框架综述

    一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...

  4. 【JAVA集合框架之工具类】

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

  5. 【JAVA集合框架之Map】

    一.概述.1.Map是一种接口,在JAVA集合框架中是以一种非常重要的集合.2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)3.Map ...

  6. 【转】Java集合框架List,Map,Set等全面介绍

    原文网址:http://android.blog.51cto.com/268543/400557 Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含 ...

  7. Java集合框架类

    java集合框架类图 Collection接口(List.Set.Queue.Stack):

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

    Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含一组接口,类的体系结构. 1. 整体框架 Java容器类库一共有两种主要类型:Collection ...

  9. Java集合框架知多少——干货!!!

    Java集合框架的组成 注意:四个接口的区别 ① Collection:存储无序的.不唯一的数据: ② List:存储有序的.不唯一的数据: ③ Set:存储无序的.唯一的数据: ④ Map:以键值对 ...

随机推荐

  1. maven 生成可执行的jar文件

    微服务的热潮,慢慢讲jar引入了码农的视线之中,从传统web开发中过来的人面对这个东西也算是个新鲜事了,接下来聊一聊在maven下生成可运行jar的那些事. Maven可以使用mvn package指 ...

  2. MySQL5.6忘记root用户名和密码

    首先我们要做的是关闭数据库,还好这个只是一个开发库,要是生产库的话使用另外一种方法修改root用户名和密码,我在另一篇文章有记载 然后我们跳过网络,跳过授权表,这个时候只有本机可以登录了,外部机器就不 ...

  3. java-工具类-读取配置文件

    java读取配置文件,当发现文件被修改后则重新加载 package com.zg.config; import java.io.File; import java.io.FileInputStream ...

  4. Linux操作系统中,*.zip、*.tar、*.tar.gz、*.tar.bz2、*.tar.xz、*.jar、*.7z等格式的压缩与解压

    zip格式 压缩: zip -r [目标文件名].zip [原文件/目录名] 解压: unzip [原文件名].zip 注:-r参数代表递归 tar格式(该格式仅仅打包,不压缩) 打包:tar -cv ...

  5. JS:offsetWidth\offsetleft 等图文解释

        网页可见区域宽: document.body.clientWidth;网页可见区域高: document.body.clientHeight;网页可见区域宽: document.body.of ...

  6. MySQL视图

    什么是视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. 理解:使用SQL语句获取的结果, ...

  7. 重写保存按钮save事件

    _saveActionEventHandler:function(event,value){ if (!_self.fireEvent("saveBefore")) return; ...

  8. shell中$0,$?,$!等的特殊用法

    变量说明: $$Shell本身的PID(ProcessID)$!Shell最后运行的后台Process的PID$?最后运行的命令的结束代码(返回值)$-使用Set命令设定的Flag一览$*所有参数列表 ...

  9. ES5语法

    ES5新语法主要是体现在Object和.Array操作,同时涉及到JSON. Function.Date 和 String类型上. 1.Object ES5最大的特点是对象扩展很多方法. 新建对象:c ...

  10. Git 学习笔记参考

    1.参考学习资料 网上资料: http://www.cnblogs.com/aoguren/p/4189086.html http://www.liaoxuefeng.com/wiki/0013739 ...