Java使用lambda自定義Arrays.sort排序規(guī)則說(shuō)明
lambda自定義Arrays.sort排序規(guī)則
1.類間排序
首先注意默認(rèn)排規(guī)則,當(dāng)使用sort(Objetc[] a)來(lái)進(jìn)行對(duì)象的自然排序,該對(duì)象必需實(shí)現(xiàn)Compareable接口,重寫(xiě)compareableTo方法,并一般在此方法中定義這3種返回值(1,0,-1)來(lái)進(jìn)行排序標(biāo)準(zhǔn)的確認(rèn)。
- return 1 時(shí),按照從小到大排序 (也可以是2,3.....正數(shù))
- return 0 時(shí),原位置不動(dòng)
- return-1 時(shí),按照從大到小排序
public class Person implements Comparable<Employee> {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
/*
* Compares person by age
* @param other another Person object
* return a negative value if this employee has a lower age than
* otherObject , 0 if the age are the same, a positive value otherwise
*/
public int compareTo(Person other) {
return Integer.compare(age, other.age);
}
}2.使用比較器(comparator)作為sort的參數(shù)(用于單個(gè)類型的排序)
// 正常方式
Arrays.sort(arr, new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return a[0]-b[0];
}
});// lambda方式
Integer[] numsArr = new Integer[10];
Arrays.sort(numsArr, (x, y) -> {
int sx = 10, sy = 10;
while (x >= sx) {
sx *= 10;
}
while (y >= sy) {
sy *= 10;
}
return (int)(sx * y + y - sy * x - x);
});需要注意傳入數(shù)組必須是對(duì)象類型
補(bǔ)充一下
注意:Arrays.sort()使用的是雙軸快排:
1.對(duì)于很小的數(shù)組(長(zhǎng)度小于27),會(huì)使用插入排序。
2.選擇兩個(gè)點(diǎn)P1,P2作為軸心,比如我們可以使用第一個(gè)元素和最后一個(gè)元素。
3.P1必須比P2要小,否則將這兩個(gè)元素交換,現(xiàn)在將整個(gè)數(shù)組分為四部分:
(1)第一部分:比P1小的元素。
(2)第二部分:比P1大但是比P2小的元素。
(3)第三部分:比P2大的元素。
(4)第四部分:尚未比較的部分。
在開(kāi)始比較前,除了軸點(diǎn),其余元素幾乎都在第四部分,直到比較完之后第四部分沒(méi)有元素。
4.從第四部分選出一個(gè)元素a[K],與兩個(gè)軸心比較,然后放到第一二三部分中的一個(gè)。
5.移動(dòng)L,K,G指向。
6.重復(fù) 4 5 步,直到第四部分沒(méi)有元素。
7.將P1與第一部分的最后一個(gè)元素交換。將P2與第三部分的第一個(gè)元素交換。
8.遞歸的將第一二三部分排序。
對(duì)于基本類型的數(shù)組如int[], double[], char[] ,Arrays類只提供了默認(rèn)的升序排列,沒(méi)有降序,需要傳入自定義比較器,使用Arrays.sort(num,c),傳入一個(gè)實(shí)現(xiàn)了Comparator接口的類的對(duì)象c。
逆序排列:
Arrays.sort(num,new Comparator<Integer>(){
public int compare(Integer a, Integer b){
return b-a;
}
});Compare函數(shù):
Compares its two arguments for order. Returns a negative integer,zero, or a positive integer as the first argument is less than, equalto, or greater than the second.
- 1:前面的數(shù)>后面的數(shù),是降序(從大到?。┡帕?,如果想要改為升序排列,就需要返回1
- -1:前面的數(shù)<后面的數(shù),是升序(從小到大)排列,不改變位置就返回-1;
- 0:二者相等,不進(jìn)行交換,也就不排序。但是要根據(jù)題目來(lái)判斷返回什么。如果數(shù)組是無(wú)序的,不能直接返回0。若保證升序排列,要返回o1-o2,降序則o2-o1。
- return 0:不交換位置,不排序
- return 1:交換位置
- return -1:不交換位置
- return o1-o2:升序排列
- return o2-o1:降序排列
compare方法中,寫(xiě)成return o1.compareTo(o2) 或者 return o1-o2表示升序;(2)寫(xiě)成return o2.compareTo(o1) 或者return o2-o1表示降序
Arrays.sort()的一些用法
Arrays.sort()重載了四類方法
sort(T[] a):對(duì)指定T型數(shù)組按數(shù)字升序排序。sort(T[] a,int formIndex, int toIndex):對(duì)指定T型數(shù)組的指定范圍按數(shù)字升序排序。sort(T[] a, Comparator c):根據(jù)指定比較器產(chǎn)生的順序?qū)χ付▽?duì)象數(shù)組進(jìn)行排序。sort(T[] a, int formIndex, int toIndex,Comparator c):根據(jù)指定比較器產(chǎn)生的順序?qū)χ付▽?duì)象數(shù)組的指定對(duì)象數(shù)組進(jìn)行排序。
參數(shù)說(shuō)明:查看源碼就知道重載的數(shù)據(jù)類型包括 Object 一共有八個(gè),其他七個(gè)就是基本類型: int , long , short , char , byte , float , double .
1.對(duì)指定T型數(shù)組按指定數(shù)值升序排序
int[] ints = new int[]{12, 4, 6, 7, 2, 8, 3, 9};// 按 數(shù)字
char[] chars = new char[]{'a', 'c', 'b', 'i', '+'};// 按 ascii 碼
byte[] bytes = new byte[]{7, 5, 6, 10, -1};// 按 字節(jié)數(shù)
Arrays.sort(ints);
Arrays.sort(chars);
Arrays.sort(bytes);
System.out.println(Arrays.toString(ints));
// 結(jié)果 :[2, 3, 4, 6, 7, 8, 9, 12]
System.out.println(Arrays.toString(chars));
// 結(jié)果 :[+, a, b, c, i]
System.out.println(Arrays.toString(bytes));
// 結(jié)果 :[-1, 5, 6, 7, 10]2.對(duì)指定T型數(shù)組的指定范圍按指定數(shù)值升序排序
int[] ints = new int[]{12, 4, 6, 7, 2, 8, 3, 9};// 按 數(shù)字
char[] chars = new char[]{'a', 'c', 'b', 'i', '+'};// 按 ascii 碼
byte[] bytes = new byte[]{7, 5, 6, 10, -1};// 按 字節(jié)數(shù)
Arrays.sort(ints, 2, 5);
Arrays.sort(chars, 2, 5);
Arrays.sort(bytes, 2, 5);
System.out.println(Arrays.toString(ints));
// 結(jié)果 :[12, 4, 2, 6, 7, 8, 3, 9]
System.out.println(Arrays.toString(chars));
// 結(jié)果 :[a, c, +, b, i]
System.out.println(Arrays.toString(bytes));
// 結(jié)果 :[7, 5, -1, 6, 10]3.根據(jù)指定比較器產(chǎn)生的順序?qū)χ付▽?duì)象數(shù)組進(jìn)行排序
(1) 一維數(shù)組降序排序
這里用降序演示一下;
?/*注意,要想改變默認(rèn)的排列順序,不能使用基本類型(int,double, char)
而要使用它們對(duì)應(yīng)的包裝類*/
Integer[] ints = new Integer[]{12, 4, 6, 7, 2, 8, 3, 9};
Arrays.sort(ints, Collections.reverseOrder());
System.out.println(Arrays.toString(ints));
// 結(jié)果 :[12, 9, 8, 7, 6, 4, 3, 2]也可以使用自定義規(guī)則
Arrays.sort(ints, new Comparator<Integer>() {
? ? @Override
? ? public int compare(Integer o1, Integer o2) {
? ? ? ? return o2 - o1;
? ? }
});
// lambda 表達(dá)式
Arrays.sort(ints, (o1, o2) -> o2 - o1);(2)二維數(shù)組按一維數(shù)組排序 升序
PS:這里提一下如果是 Integer數(shù)組 比較相等時(shí)用 equals 而不是用 == 。至于為什么請(qǐng)看 == 和 equals 的區(qū)別
int[][] nums=new int[][]{{1,3},{1,2},{5,1},{4,5},{3,3}};
//方法一
Arrays.sort(nums,new Comparator<int[]>(){
? ? @Override
? ? public int compare(int[] a,int[] b){
? ? ? ? // 當(dāng)?shù)谝痪S相等時(shí)比較第二維的
? ? ? ? if(a[0] == b[0]){
? ? ? ? ? ? return a[1]-b[1];
? ? ? ? }else{
? ? ? ? ? ? return a[0]-b[0];
? ? ? ? }
? ? }
});
// 方法二,使用 lambda 表達(dá)式
Arrays.sort(nums,(a,b) -> a[0] == b[0] ? a[1]-b[1] : a[0]-b[0]);
for (int[] num : nums) {
? ? System.out.print(Arrays.toString(num));
}
// 結(jié)果 : [1, 2][1, 3][3, 3][4, 5][5, 1](3)二維數(shù)組按二維數(shù)組排序 升序
int[][] nums=new int[][]{{1,3},{1,2},{5,1},{4,5},{3,3}};
//方法一
Arrays.sort(nums,new Comparator<int[]>(){
? ? @Override
? ? public int compare(int[] a,int[] b){
? ? ? ? // 當(dāng)?shù)诙S相等時(shí)比較第一維的
? ? ? ? if(a[1] == b[1]){
? ? ? ? ? ? return a[0]-b[0];
? ? ? ? }else{
? ? ? ? ? ? return a[1]-b[1];
? ? ? ? }
? ? }
});
// 方法二,使用 lambda 表達(dá)式
Arrays.sort(nums,(a,b) -> a[1] == b[1] ?? a[0]-b[0] : a[1]-b[1]);
for (int[] num : nums) {
? ? System.out.print(Arrays.toString(num));
}
// 結(jié)果 : [5, 1][1, 2][1, 3][3, 3][4, 5](4)二維數(shù)組降序
對(duì)調(diào)返回值哪里的順序
也就是:
// 按第一維降序
if(a[0].equals(b[0]){
? ? return b[1]-a[1];
}else{
? ? return b[0]-a[0];
}
// 結(jié)果 : [5, 1][4, 5][3, 3][1, 3][1, 2](5)類的比較
其實(shí)這個(gè)方法最重要的還是類對(duì)象的比較
由于我們可以自定義比較器,所以我們可以使用策略模式,使得在運(yùn)行時(shí)選擇不同的算法
這里就不用代碼說(shuō)明了,就是根據(jù)指定比較器產(chǎn)生的順序?qū)χ付▽?duì)象數(shù)組的指定對(duì)象數(shù)組進(jìn)行排序。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- java中Arrays.sort()排序方法舉例詳解
- Java Arrays.sort()如何實(shí)現(xiàn)對(duì)int類型數(shù)組倒序排序
- Java中Arrays.sort自定義一維數(shù)組、二維數(shù)組的排序方式
- Java的Arrays.sort()方法排序算法實(shí)例分析
- Java使用Arrays.sort()方法實(shí)現(xiàn)給對(duì)象排序
- Java Arrays.sort和Collections.sort排序?qū)崿F(xiàn)原理解析
- java通過(guò)Arrays.sort(int[] a)實(shí)現(xiàn)由大到小排序的方法實(shí)現(xiàn)
相關(guān)文章
詳解如何全注解方式構(gòu)建SpringMVC項(xiàng)目
這篇文章主要介紹了詳解如何全注解方式構(gòu)建SpringMVC項(xiàng)目,利用Eclipse構(gòu)建SpringMVC項(xiàng)目,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-10-10
使用Spring Data JPA的坑點(diǎn)記錄總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于使用Spring Data JPA的一些坑點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12
Java軟件生產(chǎn)監(jiān)控工具Btrace使用方法詳解
這篇文章主要介紹了Java軟件生產(chǎn)監(jiān)控工具Btrace使用方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
使用kotlin編寫(xiě)spring cloud微服務(wù)的過(guò)程
這篇文章主要介紹了使用kotlin編寫(xiě)spring cloud微服務(wù)的相關(guān)知識(shí),本文給大家提到配置文件的操作代碼,給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
SpringBoot整合BCrypt實(shí)現(xiàn)密碼加密
這篇文章主要為大家詳細(xì)介紹了SpringBoot整合BCrypt進(jìn)行密碼加密,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
go語(yǔ)言題解LeetCode88合并兩個(gè)有序數(shù)組示例
這篇文章主要為大家介紹了go語(yǔ)言題解LeetCode88合并兩個(gè)有序數(shù)組示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Spring Boot 使用 Swagger 構(gòu)建 RestAPI 接口文檔
這篇文章主要介紹了Spring Boot 使用 Swagger 構(gòu)建 RestAPI 接口文檔,幫助大家更好的理解和使用Spring Boot框架,感興趣的朋友可以了解下2020-10-10
Jenkins 關(guān)閉和重啟詳細(xì)介紹及實(shí)現(xiàn)
這篇文章主要介紹了Jenkins的關(guān)閉、重啟的相關(guān)資料,用jar -jar jenkins.war來(lái)啟動(dòng)jenkins服務(wù)器,那么我們?nèi)绾侮P(guān)閉或者重啟jenkins服務(wù)器呢,這里就給出實(shí)現(xiàn)的方法,需要的朋友可以參考下2016-11-11

