天天看點

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

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;

}

二、使用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)類似,定義排序規則後傳回正數,零和負數分别代表大于,等于和小于。

三、如何對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 map = new HashMap(){{

put("tom", 18);

put("jack", 25);

put("susan", 20);

put("rose", 38);

}};

ValueComparator cmptor = new ValueComparator(map);

TreeMap sorted_map = new TreeMap(cmptor);

sorted_map.putAll(map);

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

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

}

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;

}

}

}

}