概述
?????對Java對數(shù)組對象進(jìn)行排序彼硫,Java對排序問題的處理如叼。Java排序一般包括基礎(chǔ)排序和Lambda Comparator增強(qiáng)排序雳锋。為了凸顯增強(qiáng)排序的優(yōu)勢颂砸。
準(zhǔn)備
????我們先定義一個(gè)簡單的實(shí)體類:
publicclassFlux{privateString name;privateintage;??publicFlux(finalString name,finalintage){this.name = name;this.age = age;? ? }}
基本排序
????對集合排序時(shí)灶轰,為Comparator創(chuàng)建一個(gè)匿名內(nèi)部類用來排序:
newComparator() {@Overridepublicintcompare(Flux h1, Flux h2){returnh1.getName().compareTo(h2.getName());? ? }}
????簡單地用它來對Flux實(shí)體列表進(jìn)行排序:
@TestpublicvoidgivenPreLambda_whenSortingEntitiesByName_thenCorrectlySorted(){List fluxs= Lists.newArrayList(newFlux("a",10),newFlux("b",12));Collections.sort(fluxs,newComparator() {@Overridepublicintcompare(Fluxh1, Fluxh2){returnh1.getName().compareTo(h2.getName());? ? ? ? }? ? });Assert.assertThat(fluxs.get(0), equalTo(newFlux("c",12)));}
使用Lambda表達(dá)式的基本排序
??? Lambda表達(dá)式的描述谣沸,只使用簡單實(shí)用的語義即可。
(finalFluxh1,finalFluxh2)->h1.getName().compareTo(h2.getName());
????類似地笋颤,測試方法:
@TestpublicvoidwhenSortingEntitiesByName_thenCorrectlySorted(){List fluxs= Lists.newArrayList(newFlux("a",10),newFlux("c",12));??? ? fluxs.sort((Fluxh1, Fluxh2) -> h1.getName().compareTo(h2.getName()));Assert.assertThat(fluxs.get(0), equalTo(newFlux("c",12)));}
????注意:使用新的sort API乳附,這個(gè)API在Java 8里被添加到j(luò)ava.util.List —不是Collections.sort API。
沒有類型定義( Type Definitions)的基本排序
????不指定類型定義來進(jìn)一步簡化表達(dá)式 ——編譯器自己可以進(jìn)行類型判斷:
(h1,h2)->h1.getName().compareTo(h2.getName())
????測試方法:
@TestpublicvoidgivenLambdaShortForm_whenSortingEntitiesByName_thenCorrectlySorted(){List fluxs= Lists.newArrayList(newFlux("a",10),newFlux("c",12));? ? fluxs.sort((h1, h2) -> h1.getName().compareTo(h2.getName()));Assert.assertThat(fluxs.get(0), equalTo(newFlux("c",12)));}
使用靜態(tài)方法的引用來排序
????用帶有靜態(tài)方法引用的Lambda表達(dá)式去進(jìn)行排序伴澄。
???要定義compareByNameThenAge方法 ——這個(gè)方法擁有與Comparator對象里的compareTo方法完全相同:
publicstaticintcompareByNameThenAge(Flux lhs, Flux rhs){if(lhs.name.equals(rhs.name)) {returnlhs.age - rhs.age;}else{returnlhs.name.compareTo(rhs.name);? ? }}
????使用這個(gè)引用去調(diào)用fluxs.sort方法:
fluxs.sort(Flux::compareByNameThenAge);
????最終結(jié)果是一個(gè)使用靜態(tài)方法作為Comparator的有效的排序集合:
@TestpublicvoidgivenMethodDefinition_whenSortingEntitiesByNameThenAge_thenCorrectlySorted(){List fluxs = Lists.newArrayList(newFlux("a",10),newFlux("c",12));??? ? fluxs.sort(Flux::compareByNameThenAge);Assert.assertThat(fluxs.get(0), equalTo(newFlux("c",12)));}
提取Comparator進(jìn)行排序
????? 通過使用實(shí)例方法的引用和Comparator.comparing方法來避免定義比較邏輯——它會提取和創(chuàng)建一個(gè)基于那個(gè)函數(shù)的Comparable赋除。
? ?使用getName() getter方法去建造Lambda表達(dá)式并通過name對列表進(jìn)行排序:
@TestpublicvoidgivenInstanceMethod_whenSortingByNameThenAge_thenCorrectlySorted(){List?fluxs?=?Lists.newArrayList(newFlux("a",10),newFlux("c",12));? ? Collections.sort(fluxs, Comparator.comparing(Flux::getName));Assert.assertThat(fluxs.get(0), equalTo(newFlux("c",12)));}
?反轉(zhuǎn)排序
?????? JDK 8提供了一個(gè)方法用來反轉(zhuǎn)Comparator(reverse Comparator)——可以快速地反轉(zhuǎn)排序結(jié)果:
@TestpublicvoidwhenSortingByNameReversed_thenCorrectlySorted(){? ? List<Flux> fluxs = Lists.newArrayList(newFlux("a",10),newFlux("c",12));? ? Comparator<Flux> comparator = (h1, h2) -> h1.getName().compareTo(h2.getName());??? ? fluxs.sort(comparator.reversed());Assert.assertThat(fluxs.get(0), equalTo(newFlux("a",10)));}
多條件排序
????????比較操作的Lambda表達(dá)式不一定都是這么簡單的——我們同樣可以編寫更復(fù)雜的表達(dá)式,先根據(jù)name后根據(jù)age來對實(shí)體進(jìn)行排序:
@TestpublicvoidwhenSortingEntitiesByNameThenAge_thenCorrectlySorted(){? ? List<Flux> fluxs = Lists.newArrayList(newFlux("a",12),newFlux("a",10),newFlux("z",12));??? ? fluxs.sort((lhs, rhs) -> {if(lhs.getName().equals(rhs.getName())) {returnlhs.getAge() - rhs.getAge();}else{returnlhs.getName().compareTo(rhs.getName());? ? ? ? }? ? });Assert.assertThat(fluxs.get(0), equalTo(newFlux("a",10)));}
多條件組合排序
???????比較邏輯——先根據(jù)name進(jìn)行排序其次是age非凌,同樣可以通過Comparator新的組合支持來實(shí)現(xiàn)举农。
????????從JDK 8開始,可以把多個(gè)Comparator鏈在一起(chain together)去建造更復(fù)雜的比較邏輯:
@TestpublicvoidcompositionSortedByNameThenAge(){? ? List<Flux> fluxs = Lists.newArrayList(newFlux("a",12),newFlux("a",10),newFlux("z",12));??? ? fluxs.sort(Comparator.comparing(Flux::getName).thenComparing(Flux::getAge));Assert.assertThat(fluxs.get(0), equalTo(newFlux("a",10)));}
技術(shù)交流:歡迎關(guān)注