sort()排序(Comparable、Comparator)
在收集對象之后,對對象進(jìn)行排序是常用的動作。不用親自操作排序算法Java.util. Collections提供有sort()方法。由于必須有索引才能進(jìn)行排序,因此 Collections的sort()方法接受List操作對象。例如:
package coll_map;import java.util.*;public class SortDemo {public static void main(String[] args) {List nums=Arrays.asList(3,6,2,7,5,9,0);Collections.sort(nums);System.out.println(nums);} }復(fù)制代碼1.操作 Comparable package coll_map;import java.util.*;class Sort2 {private String name;private String ID;private int balance;Sort2(String name, String ID, int balance) {this.name = name;this.balance = balance;this.ID = ID;}@Overridepublic String toString() {return String.format("賬戶(%s,%s,%d)", name,ID,balance);} }public class Account{public static void main(String[] args) {List accounts=Arrays.asList(new Sort2("zhangsan","9958X",999),new Sort2("lisi","8779g",577),new Sort2("wanger","99098X",6988));Collections.sort(accounts);System.out.println(accounts);}} 復(fù)制代碼拋錯: java.lang.ClassCastException 是因為Collections的sort方法,不知道是根據(jù) Account的name、ID或 balance進(jìn)行排序。sort()方法要求被排序的對象必須操作java.lang. Comparable接口,這個接口有個 compareto()方法必須返回大于0、等于0或小于0的數(shù):
package coll_map;import java.util.*;class Sort2 implements Comparable<Sort2>{private String name;private String ID;private int balance;Sort2(String name, String ID, int balance) {this.name = name;this.balance = balance;this.ID = ID;}@Overridepublic String toString() {return String.format("賬戶(%s,%s,%d)", name,ID,balance);}@Overridepublic int compareTo(Sort2 o) {// TODO 自動生成的方法存根return this.balance-o.balance;//判斷排序條件} }public class Account{public static void main(String[] args) {List accounts=Arrays.asList(new Sort2("zhangsan","9958X",999),new Sort2("lisi","8779g",577),new Sort2("wanger","99098X",6988));Collections.sort(accounts);System.out.println(accounts);}} 復(fù)制代碼collections的sot()方法在取得a對象與b對象進(jìn)行比較時,會先將a對象扮演(Cast)為 comparable(也因此若對象沒操作 Comparable,將會拋出 Classcastexception),然后調(diào)用 a.compareto(b),如果a對象順序上小于b對象則返回小于0的值,若順序上相等則返回0,若順序上a大于b則返回大于0的值。因此,上面的范例,將會依余額從小到大排列賬戶對象。前面的Sort類中,可以直接對 Integer進(jìn)行排序,因為Integer就有操作 Comparable接口。 2.操作Comparator String有操作Comparable:
package coll_map;import java.util.*;public class SortDemo {public static void main(String[] args) {List words=Arrays.asList("D","A","H","Y","E");Collections.sort(words);//如果只想用String的compareTo方法可以:words.sort(String::compareTo);System.out.println(words);} }復(fù)制代碼 但是如果有對象無法操作Comparable、拿不到原始碼或者不能修改原始碼。 比如讓String排序結(jié)果反過來,就算修改String. Java后重新編譯為 String.clas放回 rt jar中,也只有這個的JRE可以用,這已經(jīng)不是標(biāo)準(zhǔn)API了。繼承 string后再重新定義 compareto()也不可能,因為 String聲明為 final,不能被繼承。 Collections的sort()方法有另一個重載版本,可接受 Java util. **Comparator接口的操作對象,如果使用這個版本,排序方式將根據(jù) Comparator的 compare()定義來決定。**例如: package coll_map; import java.util.*;public class SortDemo {public static void main(String[] args) {List<String> words=Arrays.asList("D","A","H","Y","E");Collections.sort(words,new StringSort());System.out.println(words);} } class StringSort implements Comparator<String>{@Overridepublic int compare(String o1, String o2) {// TODO 自動生成的方法存根return -o1.compareTo(o2);} } 復(fù)制代碼Comparator的 compare()會傳入兩個對象,如果o1順序上小于o2則返回小于0的值,順序相等則返回0,順序上o1大于o2則返回大于0的值。在這個范例中,由于 string本身就是 Comparable,所以將 compareto()返回的值乘上-1,就可以調(diào)換排列順序。
package coll_map;import java.util.*;public class SortDemo {public static void main(String[] args) {List<String> words=Arrays.asList("D","A","H","Y","E");//Collections.sort(words,(o1,o2) ->-o1.compareTo(o2));利用Lambda語法words.sort((o1,o2) ->-o1.compareTo(o2));//更簡單利用Lambda語法System.out.println(words);} }復(fù)制代碼在Java的規(guī)范中,與順序有關(guān)的行為,通常要不對象本身是 Comparable,要不就是另行指定 Comparator對象告知如何排序。 例如,如果想針對數(shù)組進(jìn)行排序,可以使用java.util.Arrays的sort()方法,如果查詢API文件,會發(fā)現(xiàn)該方法針對對象排序時有兩個版本:一個版本是你收集在數(shù)組中的對象必須是 Comparable()否則會拋出Classcastexception ,另一個版本則可以傳入 compa rato指定排序方式.
Set的操作類之一java. util. TreeSet不僅擁有收集不重復(fù)對象的能力,還可用紅黑樹方式排序收集的對象,條件就是收集的對象必須是 comparable(否則會拋出 Classcastexception)或者是在創(chuàng)建TreeSet時指定 Comparator 對象。 Queue的操作類之一 java util. Priorityqueue也是,收集至 Priorityqueue的對象,會根據(jù)你指定的優(yōu)先權(quán)來決定對象在隊列中的序,優(yōu)先權(quán)的告知,要不就是對象必須是 comparable(否則會拋出Classcastexception)或者是創(chuàng)建Priorityqueue時指定Comparator對象。 如果有個List中某些索引處包括null,現(xiàn)在讓null排在最前頭,之后依字符串的長度由大到小排序,這樣重新定義compare:
當(dāng)然其實可以利用高級語義API:
package coll_map; import java.util.*; import static java.util.Comparator.*;public class SortDemo {public static void main(String[] args) {List<String> words=Arrays.asList("D","A","H","Y","E");words.sort(nullsFirst(reverseOrder));//高級語義System.out.println(words);} }復(fù)制代碼reverseOrder()返回的 Comparator會是 Comparable對象上定義順序的反序, nullsFirst接受 Comparator,在其定義的順序上加上讓null排在最前面的規(guī)則。 可以看到 import static適當(dāng)?shù)倪\用,可以讓程序碼表達(dá)出本身操作的意圖相比以下程序代碼來說清楚許多:
words.sort(Comparator.nullsFirst(Comparator.reverseOrder)); 復(fù)制代碼Conparator上還有很多方法可以使用,例如 comparing與 thenComparing等方法,要運用這些方法,得了解更多JDK8的 Lambda特性,例如位于java.util.function套件中的 Function等接口的意義
總結(jié)
以上是生活随笔為你收集整理的sort()排序(Comparable、Comparator)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webpack----常规配置
- 下一篇: spring bean 小记