




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第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)部類可以簡化為Lambda表達(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類型簡寫:
students.sort((h1,h2)-h1.getName().compareTo(h2.getName()));
至此,我們整段排序邏輯可以簡化為:
@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));
多條件排序
我們在靜態(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));
從邏輯來看,多條件排序就是先判斷第一級條件,如果相等,再判斷第二級條件,依次類推。在Java8中可以使用comparing和一系列thenComparing表示多級條件判斷,上面的邏輯可以簡化為:
@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è)的,用于表示多級條件判斷,這也是函數(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簡化書寫:
@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)倒序排列,用起來也是很簡單:
@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值的判斷
前面的例子中都是有值元素排序,能夠覆蓋大部分場景,但有時(shí)候我們還是會(huì)碰到元素中存在null的情況:
列表中的元素是null
列表中的元素參與排序條件的字段是null
如果還是使用前面的那些實(shí)現(xiàn),我們會(huì)碰到NullPointException異常,即NPE,簡單演示一下:
@Test
voidsortedNullGotNPE(){
finalListStudentstudents=Lists.newArrayList(
null,
newStudent("Snoopy",12),
null
Assertions.assertThrows(NullPointerException.class,
()-students.sort(Cparing(Student::getName)));
所以,我們需要考慮這些場景。
元素是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));
是不是很簡單,接下來我們看下如何實(shí)現(xiàn)排序條件的字段是null的邏輯。
排序條件的字段是nu
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 竹材采運(yùn)安全風(fēng)險(xiǎn)識(shí)別與防范考核試卷
- 藥品行業(yè)政策變動(dòng)與影響考核試卷
- 堅(jiān)定文化自信宣講
- 數(shù)字智慧方案5474丨人力資源管理數(shù)字化轉(zhuǎn)型解決方案1
- 中學(xué)生法制教育專題
- 公司2024年慶元旦活動(dòng)方案細(xì)選
- 環(huán)保兒童視頻課件
- 2019-2025年稅務(wù)師之稅法一通關(guān)提分題庫及完整答案
- 《軸流泵維護(hù)》課件
- 2025年醫(yī)用穿刺器械項(xiàng)目合作計(jì)劃書
- 心電監(jiān)護(hù)操作評分標(biāo)準(zhǔn)
- 三年級美術(shù)下冊 《多彩的窗戶》教學(xué)課件
- JJG 700 -2016氣相色譜儀檢定規(guī)程-(高清現(xiàn)行)
- 優(yōu)秀病例演講比賽PPT
- 技術(shù)報(bào)告審簽表
- GB∕T 25684.5-2021 土方機(jī)械 安全 第5部分:液壓挖掘機(jī)的要求
- 中國基層胸痛中心認(rèn)證標(biāo)準(zhǔn)(第三版)
- 雞的解剖步驟及病
- 噴涂件檢驗(yàn)通用規(guī)范
- 石方爆破及安全施工工藝流程圖
- 市場部經(jīng)理年終總結(jié)PPT模板
評論
0/150
提交評論