java 自定义排序_Java集合框架实现自定义排序

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

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

}

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

Arrays.sort(charArr);

for(int i=0;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 list);

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

如果待排序的列表中是数字或者字符,可以直接使用Collections.sort(list);

当需要排序的集合或数组不是单纯的数字型时,需要自己定义排序规则,实现一个Comparator比较器。

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

Comparable 是排序接口,一个类实现了Comparable接口,就意味着该类支持排序。

Comparable 的定义如下:

public interface Comparable {

public int compareTo(T o);

}

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

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

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

Comparator接口的定义如下:

public interface Comparator {

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 map = new HashMap(){{

put("tom", 18);

put("jack", 25);

put("susan", 20);

put("rose", 38);

}};

ValueComparator cmptor = new ValueComparator(map);

/**

* 转换为有序的TreeMap进行输出

*/

TreeMap sorted_map = new TreeMap(cmptor);

sorted_map.putAll(map);

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

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

}

/**

* 转换为有序的list进行排序

*/

List keys = new ArrayList(map.keySet());

Collections.sort(keys, cmptor);

for(String key : keys) {

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

}

}

static class ValueComparator implements Comparator {

HashMap base_map;

public ValueComparator(HashMap 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

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

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

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

}

}

}

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值