




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Java進(jìn)階使用Lambda表達(dá)式實(shí)現(xiàn)超強(qiáng)的排序功能因?yàn)槎x的Comparator是使用name字段排序,在Java中,String類型的排序是通過單字符的ASCII碼順序判斷的,J排在T的前面,所以Jerry排在第一個(gè)。
使用Lambda表達(dá)式替換Comparator匿名內(nèi)部類
使用過Java8的Lamdba的應(yīng)該知道,匿名內(nèi)部類可以簡(jiǎn)化為L(zhǎng)ambda表達(dá)式為:
Collections.sort(students,(Studenth1,Studenth2)-h1.getName().compareTo(h2.getName()));
在Java8中,List類中增加了sort方法,所以Collections.sort可以直接替換為:
students.sort((Studenth1,Studenth2)-h1.getName().compareTo(h2.getName()));
根據(jù)Java8中Lambda的類型推斷,我們可以將指定的Student類型簡(jiǎn)寫:
students.sort((h1,h2)-h1.getName().compareTo(h2.getName()));
至此,我們整段排序邏輯可以簡(jiǎn)化為:
@Test
voidbaseSortedLambdaWithInferring(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
students.sort((h1,h2)-h1.getName().compareTo(h2.getName()));
Assertions.assertEquals(students.get(0),newStudent("Jerry",12));
通過靜態(tài)方法抽取公共的Lambda表達(dá)式
我們可以在Student中定義一個(gè)靜態(tài)方法:
publicstaticintcompareByNameThenAge(Students1,Students2){
if(.equals()){
returnIpare(s1.age,s2.age);
}else{
returnpareTo();
這個(gè)方法需要返回一個(gè)int類型參數(shù),在Java8中,我們可以在Lambda中使用該方法:
@Test
voidsortedUsingStaticMethod(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
students.sort(Student::compareByNameThenAge);
Assertions.assertEquals(students.get(0),newStudent("Jerry",12));
借助Comparator的comparing方法
在Java8中,Comparator類新增了comparing方法,可以將傳遞的Function參數(shù)作為比較元素,比如:
@Test
voidsortedUsingComparator(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
students.sort(Cparing(Student::getName));
Assertions.assertEquals(students.get(0),newStudent("Jerry",12));
多條件排序
我們?cè)陟o態(tài)方法一節(jié)中展示了多條件排序,還可以在Comparator匿名內(nèi)部類中實(shí)現(xiàn)多條件邏輯:
@Test
voidsortedMultiCondition(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12),
newStudent("Jerry",13)
students.sort((s1,s2)-{
if(s1.getName().equals(s2.getName())){
returnIpare(s1.getAge(),s2.getAge());
}else{
returns1.getName().compareTo(s2.getName());
Assertions.assertEquals(students.get(0),newStudent("Jerry",12));
從邏輯來看,多條件排序就是先判斷第一級(jí)條件,如果相等,再判斷第二級(jí)條件,依次類推。在Java8中可以使用comparing和一系列thenComparing表示多級(jí)條件判斷,上面的邏輯可以簡(jiǎn)化為:
@Test
voidsortedMultiConditionUsingComparator(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12),
newStudent("Jerry",13)
students.sort(Cparing(Student::getName).thenComparing(Student::getAge));
Assertions.assertEquals(students.get(0),newStudent("Jerry",12));
這里的thenComparing方法是可以有多個(gè)的,用于表示多級(jí)條件判斷,這也是函數(shù)式編程的方便之處。
在Stream中進(jìn)行排序
Java8中,不但引入了Lambda表達(dá)式,還引入了一個(gè)全新的流式API:StreamAPI,其中也有sorted方法用于流式計(jì)算時(shí)排序元素,可以傳入Comparator實(shí)現(xiàn)排序邏輯:
@Test
voidstreamSorted(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
finalComparatorStudentcomparator=(h1,h2)-h1.getName().compareTo(h2.getName());
finalListStudentsortedStudents=students.stream()
.sorted(comparator)
.collect(Collectors.toList());
Assertions.assertEquals(sortedStudents.get(0),newStudent("Jerry",12));
同樣的,我們可以通過Lambda簡(jiǎn)化書寫:
@Test
voidstreamSortedUsingComparator(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
finalComparatorStudentcomparator=Cparing(Student::getName);
finalListStudentsortedStudents=students.stream()
.sorted(comparator)
.collect(Collectors.toList());
Assertions.assertEquals(sortedStudents.get(0),newStudent("Jerry",12));
倒序排列
調(diào)轉(zhuǎn)排序判斷
排序就是根據(jù)compareTo方法返回的值判斷順序,如果想要倒序排列,只要將返回值取返即可:
@Test
voidsortedReverseUsingComparator2(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
finalComparatorStudentcomparator=(h1,h2)-h2.getName().compareTo(h1.getName());
students.sort(comparator);
Assertions.assertEquals(students.get(0),newStudent("Tom",10));
可以看到,正序排列的時(shí)候,我們是h1.getName().compareTo(h2.getName()),這里我們直接倒轉(zhuǎn)過來,使用的是h2.getName().compareTo(h1.getName()),也就達(dá)到了取反的效果。在Java的Collections中定義了一個(gè)java.util.Collections.ReverseComparator內(nèi)部私有類,就是通過這種方式實(shí)現(xiàn)元素反轉(zhuǎn)。
借助Comparator的reversed方法倒序
在Java8中新增了reversed方法實(shí)現(xiàn)倒序排列,用起來也是很簡(jiǎn)單:
@Test
voidsortedReverseUsingComparator(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
finalComparatorStudentcomparator=(h1,h2)-h1.getName().compareTo(h2.getName());
students.sort(comparator.reversed());
Assertions.assertEquals(students.get(0),newStudent("Tom",10));
在Cparing中定義排序反轉(zhuǎn)
comparing方法還有一個(gè)重載方法,java.util.Comparator#comparing(java.util.function.FunctionsuperT,extendsU,java.util.ComparatorsuperU),第二個(gè)參數(shù)就可以傳入Comparator.reverseOrder(),可以實(shí)現(xiàn)倒序:
@Test
voidsortedUsingComparatorReverse(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
students.sort(Cparing(Student::getName,Comparator.reverseOrder()));
Assertions.assertEquals(students.get(0),newStudent("Jerry",12));
在Stream中定義排序反轉(zhuǎn)
在Stream中的操作與直接列表排序類似,可以反轉(zhuǎn)Comparator定義,也可以使用Comparator.reverseOrder()反轉(zhuǎn)。實(shí)現(xiàn)如下:
@Test
voidstreamReverseSorted(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
finalComparatorStudentcomparator=(h1,h2)-h2.getName().compareTo(h1.getName());
finalListStudentsortedStudents=students.stream()
.sorted(comparator)
.collect(Collectors.toList());
Assertions.assertEquals(sortedStudents.get(0),newStudent("Tom",10));
@Test
voidstreamReverseSortedUsingComparator(){
finalListStudentstudents=Lists.newArrayList(
newStudent("Tom",10),
newStudent("Jerry",12)
finalListStudentsortedStudents=students.stream()
.sorted(Cparing(Student::getName,Comparator.reverseOrder()))
.collect(Collectors.toList());
Assertions.assertEquals(sortedStudents.get(0),newStudent("Tom",10));
null值的判斷
前面的例子中都是有值元素排序,能夠覆蓋大部分場(chǎng)景,但有時(shí)候我們還是會(huì)碰到元素中存在null的情況:
列表中的元素是null
列表中的元素參與排序條件的字段是null
如果還是使用前面的那些實(shí)現(xiàn),我們會(huì)碰到NullPointException異常,即NPE,簡(jiǎn)單演示一下:
@Test
voidsortedNullGotNPE(){
finalListStudentstudents=Lists.newArrayList(
null,
newStudent("Snoopy",12),
null
Assertions.assertThrows(NullPointerException.class,
()-students.sort(Cparing(Student::getName)));
所以,我們需要考慮這些場(chǎng)景。
元素是null的笨拙實(shí)現(xiàn)
最先想到的就是判空:
@Test
voidsortedNullNoNPE(){
finalListStudentstudents=Lists.newArrayList(
null,
newStudent("Snoopy",12),
null
students.sort((s1,s2)-{
if(s1==null){
returns2==null0:1;
}elseif(s2==null){
return-1;
returns1.getName().compareTo(s2.getName());
Assertions.assertNotNull(students.get(0));
Assertions.assertNull(students.get(1));
Assertions.assertNull(students.get(2));
我們可以將判空的邏輯抽取出一個(gè)Comparator,通過組合方式實(shí)現(xiàn):
classNullComparatorTimplementsComparatorT{
privatefinalComparatorTreal;
NullComparator(ComparatorsuperTreal){
this.real=(ComparatorT)real;
@Override
publicintcompare(Ta,Tb){
if(a==null){
return(b==null)0:1;
}elseif(b==null){
return-1;
}else{
return(real==null)0:pare(a,b);
在Java8中已經(jīng)為我們準(zhǔn)備了這個(gè)實(shí)現(xiàn)。
使用Comparator.nullsLast和Comparator.nullsFirst
使用Comparator.nullsLast實(shí)現(xiàn)null在結(jié)尾:
@Test
voidsortedNullLast(){
finalListStudentstudents=Lists.newArrayList(
null,
newStudent("Snoopy",12),
null
students.sort(Comparator.nullsLast(Cparing(Student::getName)));
Assertions.assertNotNull(students.get(0));
Assertions.assertNull(students.get(1));
Assertions.assertNull(students.get(2));
使用Comparator.nullsFirst實(shí)現(xiàn)null在開頭:
@Test
voidsortedNullFirst(){
finalListStudentstudents=Lists.newArrayList(
null,
newStudent("Snoopy",12),
null
students.sort(Comparator.nullsFirst(Cparing(Student::getName)));
Assertions.assertNull(students.get(0));
Assertions.assertNull(students.get(1));
Assertions.assertNotNull(students.get(2));
是不是很簡(jiǎn)單,接下來我們看下如何實(shí)現(xiàn)排序條件的字段是null的邏輯。
排序條件的字段是nu
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 湖南省天壹名校聯(lián)盟2025屆高三5月適應(yīng)性考試(生物)
- 停車場(chǎng)合同范例
- 醫(yī)療供應(yīng)鏈中區(qū)塊鏈的追溯應(yīng)用研究
- 辦公室醫(yī)療融合發(fā)展兒童健康成長(zhǎng)與科學(xué)補(bǔ)鈣研究
- led燈工程合同范例
- 高中物理選修3-5重要知識(shí)點(diǎn)總結(jié)模版
- 醫(yī)療團(tuán)隊(duì)協(xié)作中的溝通與信任建設(shè)
- 醫(yī)療行業(yè)數(shù)據(jù)透明度與質(zhì)量控制的平衡點(diǎn)
- 區(qū)塊鏈技術(shù)助力構(gòu)建高效的物流供應(yīng)鏈體系
- 醫(yī)療數(shù)據(jù)智能化處理技術(shù)及其實(shí)踐
- 2022年注冊(cè)規(guī)劃師實(shí)務(wù)試題及答案
- 心電監(jiān)護(hù)操作評(píng)分標(biāo)準(zhǔn)
- DB62∕T 3176-2019 建筑節(jié)能與結(jié)構(gòu)一體化墻體保溫系統(tǒng)應(yīng)用技術(shù)規(guī)程
- 優(yōu)秀病例演講比賽PPT
- 技術(shù)報(bào)告審簽表
- GB∕T 25684.5-2021 土方機(jī)械 安全 第5部分:液壓挖掘機(jī)的要求
- 電氣爐焊接工藝的自動(dòng)化控制線設(shè)計(jì)
- 剪式汽車舉升機(jī)設(shè)計(jì)說明
- 中國(guó)基層胸痛中心認(rèn)證標(biāo)準(zhǔn)(第三版)
- 雞的解剖步驟及病
- 常見食物的性味歸經(jīng)附表
評(píng)論
0/150
提交評(píng)論