參考良葛格網站與官方API的Comparator與Comparable筆記
前言
「在Java的規範中,跟順序有關的行為,通常要不物件本身是Comparable
,要不就是另行指定Comparator
物件告知如何排序。」
引用自良葛格介紹Comparabla與Comparatorㄧ文中。
Java 8以前
使用Collections.sort()方法傳入欲排序的List,但前提是該物件必須實作Comparable介面,否則會報錯
public static <T extends Comparable<? super T>> void sort(List<T> list)
Java 8以後
List介面加入sort默認方法可以使用
default void sort(Comparator<? super E> c)
Comparable Interface
Comparable介面底下指有一個抽象方法需實作,ㄧ般來說常見的String、Integer、Double、BigDecimal....等都有實作Comparable,若需要課製化比較規則會使用Comparator
int compareTo(T o)
Compares this object with the specified object for order.
Comparator Interface
- Functional Interface:
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
Comparator為ㄧ個Functional Interface 可供lamda expression or 其他方法參考,其中compare為其抽象方法,用法與Comparable介面的compareTo類似,
int compare(T o1, T o2)
Compares its two arguments for order.
Comparable v.s. Comparator
- 從英文字面上比較
Comparable:可比較的--->通常用在物件implements使用,例如String、Integer、BigDecimal.....
Comparator:比較器--->應用範圍廣,此介面提供很多默認方法供lamda expression使用
- 在某些情況下雖然物件有實作Comparable但我們卻無法改變其排序行為,例如String類別想要讓排序結果反序,此時我們可以時作ㄧ個String比較器供Collections.sort使用
- Collections.sort()有多載方法供Comparable與Comparator使用
Collections.sort()的範例
public static <T extends Comparable<? super T>> void sort(List<T> list) API連結
public static <T> void sort(List<T> , Comparator<? super T> c) API連結
public class main {
public static void main(String[] args) throws InterruptedException {
List<String> list = Arrays.asList("Java","Python","C_sharp","R","Scala","Kotlin","Delphi");
//直接按物件Comparable排序
Collections.sort(list);
System.out.println(list);//
//比較器正規寫法 按字母反序
Collections.sort(list, new StringComparator());
System.out.println(list);
//匿名類別寫法 按照字串長度由小到大
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}} );
System.out.println(list);// [R, Java, Scala, Python, Kotlin, Delphi, C_sharp]
//lamda寫法 按照字串長度由大到小
Collections.sort(list,(u,v)-> -(u.length()-v.length()));
System.out.println(list); //[C_sharp, Python, Kotlin, Delphi, Scala, Java, R]
}
}
class StringComparator implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
return -1*o1.compareTo(o2);
}
}
List介面提供的sort默認方法
default void sort(Comparator<? super E> c) API連結
範例同上Collections.sort()傳入Comparator的方法
Comparator提供的默認方法應用
- comparing
static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor) API連結
- reversed
default Comparator<T> reversed()
public static void main(String[] args) throws InterruptedException {
List<String> list = Arrays.asList("Java","Python","C_sharp","R","Scala","Kotlin","Delphi");
list.sort(Comparator.comparing(String::length));
list.sort(Comparator.comparing( s-> s.length()) );
list.sort(Comparator.<String,Integer>comparing(s->s.length()));
System.out.println(list);//[R, Java, Scala, Python, Kotlin, Delphi, C_sharp]
//reverse
list.sort(Comparator.comparing(String::length).reversed());
System.out.println(list);//[C_sharp, Python, Kotlin, Delphi, Scala, Java, R]
}
Reference: