Java使用lambda自定義Arrays.sort排序規(guī)則說明
lambda自定義Arrays.sort排序規(guī)則
1.類間排序
首先注意默認(rèn)排規(guī)則,當(dāng)使用sort(Objetc[] a)來進行對象的自然排序,該對象必需實現(xiàn)Compareable接口,重寫compareableTo方法,并一般在此方法中定義這3種返回值(1,0,-1)來進行排序標(biāo)準(zhǔn)的確認(rèn)。
- return 1 時,按照從小到大排序 (也可以是2,3.....正數(shù))
- return 0 時,原位置不動
- return-1 時,按照從大到小排序
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ù)(用于單個類型的排序)
// 正常方式 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ù)組必須是對象類型
補充一下
注意:Arrays.sort()使用的是雙軸快排:
1.對于很小的數(shù)組(長度小于27),會使用插入排序。
2.選擇兩個點P1,P2作為軸心,比如我們可以使用第一個元素和最后一個元素。
3.P1必須比P2要小,否則將這兩個元素交換,現(xiàn)在將整個數(shù)組分為四部分:
(1)第一部分:比P1小的元素。
(2)第二部分:比P1大但是比P2小的元素。
(3)第三部分:比P2大的元素。
(4)第四部分:尚未比較的部分。
在開始比較前,除了軸點,其余元素幾乎都在第四部分,直到比較完之后第四部分沒有元素。
4.從第四部分選出一個元素a[K],與兩個軸心比較,然后放到第一二三部分中的一個。
5.移動L,K,G指向。
6.重復(fù) 4 5 步,直到第四部分沒有元素。
7.將P1與第一部分的最后一個元素交換。將P2與第三部分的第一個元素交換。
8.遞歸的將第一二三部分排序。
對于基本類型的數(shù)組如int[], double[], char[] ,Arrays類只提供了默認(rèn)的升序排列,沒有降序,需要傳入自定義比較器,使用Arrays.sort(num,c),傳入一個實現(xiàn)了Comparator接口的類的對象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ù)題目來判斷返回什么。如果數(shù)組是無序的,不能直接返回0。若保證升序排列,要返回o1-o2,降序則o2-o1。
- return 0:不交換位置,不排序
- return 1:交換位置
- return -1:不交換位置
- return o1-o2:升序排列
- return o2-o1:降序排列
compare方法中,寫成return o1.compareTo(o2) 或者 return o1-o2表示升序;(2)寫成return o2.compareTo(o1) 或者return o2-o1表示降序
Arrays.sort()的一些用法
Arrays.sort()重載了四類方法
sort(T[] a)
:對指定T型數(shù)組按數(shù)字升序排序。sort(T[] a,int formIndex, int toIndex)
:對指定T型數(shù)組的指定范圍按數(shù)字升序排序。sort(T[] a, Comparator c)
:根據(jù)指定比較器產(chǎn)生的順序?qū)χ付▽ο髷?shù)組進行排序。sort(T[] a, int formIndex, int toIndex,Comparator c)
:根據(jù)指定比較器產(chǎn)生的順序?qū)χ付▽ο髷?shù)組的指定對象數(shù)組進行排序。
參數(shù)說明:查看源碼就知道重載的數(shù)據(jù)類型包括 Object 一共有八個,其他七個就是基本類型: int , long , short , char , byte , float , double .
1.對指定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.對指定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ū)χ付▽ο髷?shù)組進行排序
(1) 一維數(shù)組降序排序
這里用降序演示一下;
?/*注意,要想改變默認(rèn)的排列順序,不能使用基本類型(int,double, char) 而要使用它們對應(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 表達式 Arrays.sort(ints, (o1, o2) -> o2 - o1);
(2)二維數(shù)組按一維數(shù)組排序 升序
PS:這里提一下如果是 Integer數(shù)組 比較相等時用 equals 而不是用 == 。至于為什么請看 == 和 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相等時比較第二維的 ? ? ? ? if(a[0] == b[0]){ ? ? ? ? ? ? return a[1]-b[1]; ? ? ? ? }else{ ? ? ? ? ? ? return a[0]-b[0]; ? ? ? ? } ? ? } }); // 方法二,使用 lambda 表達式 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相等時比較第一維的 ? ? ? ? if(a[1] == b[1]){ ? ? ? ? ? ? return a[0]-b[0]; ? ? ? ? }else{ ? ? ? ? ? ? return a[1]-b[1]; ? ? ? ? } ? ? } }); // 方法二,使用 lambda 表達式 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ù)組降序
對調(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)類的比較
其實這個方法最重要的還是類對象的比較
由于我們可以自定義比較器,所以我們可以使用策略模式,使得在運行時選擇不同的算法
這里就不用代碼說明了,就是根據(jù)指定比較器產(chǎn)生的順序?qū)χ付▽ο髷?shù)組的指定對象數(shù)組進行排序。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java?工作流引擎設(shè)計實現(xiàn)解析流程定義文件
這篇文章主要為大家介紹了java?工作流引擎設(shè)計與實現(xiàn)及流程定義文件解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05(starters)springboot-starter整合阿里云datahub方式
這篇文章主要介紹了(starters)springboot-starter整合阿里云datahub方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11spring security數(shù)據(jù)庫表結(jié)構(gòu)實例代碼
這篇文章主要介紹了spring security數(shù)據(jù)庫表結(jié)構(gòu)實例代碼,需要的朋友可以參考下2017-09-09RabbitMQ交換機使用場景和消息可靠性總結(jié)分析
這篇文章主要為大家介紹了RabbitMQ交換機使用場景和消息可靠性總結(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01JAVA8妙用Optional解決判斷Null為空的問題方法
本文主要介紹了JAVA8妙用Optional解決判斷Null為空的問題方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10Java畢業(yè)設(shè)計之多用戶宿舍管理系統(tǒng)的實現(xiàn)
這篇文章主要介紹了基于Java實現(xiàn)的多用戶宿舍管理系統(tǒng),本文采用了jsp、servlet、jdbc等技術(shù),文中示例代碼講解詳細,需要的可以參考一下2022-02-02