Java Comparator接口學習筆記
阿新 • • 發佈:2018-08-25
print req 依據 sin 例如 cto ret ace 鏈式
① 靜態方法
② 靜態方法
③ 默認方法
Comparator
是一個泛型函數式接口,T
表示待比較對象的類型:
@FunctionalInterface
public interface Comparator<T> {
}
1. 抽象方法
唯一的非Object抽象方法: compare
int compare(T o1, T o2)
根據o1, o2的大小關系返回:負數、0、正數
其比較邏輯依賴於賦值給Comparator
類型變量的Lambda表達式、Comparator
對象等:
Comparator<String> comparator = Comparator.comparingInt(String::length); // 比較String類對象的length System.out.println(comparator.compare("Tom", "Jerry")); // -1
2. 常用靜態/默認方法
① 靜態方法comparing
// 源碼1 public static <T, U extends Comparable<? super U>> Comparator<T> comparing( Function<? super T, ? extends U> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2)); }
返回值:
comparing
返回一個T
類型的Comparator
對象(也就是用於比較T
類型對象的Comparator
)參數:
comparing
的參數是一個Function
類型,它接收T
類型及T
的超類型, 返回U
類型及U
的子類型。keyExtractor
用Lambda表達式實現例如,輸入
String
,提取其長度:Comparator<String> keyComparator = Comparator.comparing(String::length); keyComparator.compare("Tom", "Jerry");
- 函數體:
- 首先,確保
keyExtractor
null
- 然後,返回一個Lambda表達式,該表達式對
c1
和c2
提取出來的key
進行比較 (用的是c1
和c2
類實現的compareTo()
進行比較)
- 首先,確保
public static <T, U> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator)
{
Objects.requireNonNull(keyExtractor);
Objects.requireNonNull(keyComparator);
return (Comparator<T> & Serializable)
(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
keyExtractor.apply(c2));
}
與上面類似,只不過將key
的比較邏輯由compareTo()
替換成了自定義的比較邏輯
實例:
package Lambda.ComparatorDemo;
import java.util.Arrays;
import java.util.Comparator;
class Person {
private String fname;
private String lname;
public Person(String fname, String lname) {
this.fname = fname;
this.lname = lname;
}
public String getFname() {
return fname;
}
public String getLname() {
return lname;
}
@Override
public String toString() {
return fname + " " + lname;
}
}
public class ComparingDemo {
public static void main(String[] args) {
Person p1 = new Person("Tom", "Kenn");
Person p2 = new Person("Alice", "Zed");
Person[] persons1 = {p1, p2};
Person[] persons2 = persons1.clone();
// 依據First Name排序(用的是String類的compareTo的比較邏輯)
Arrays.sort(persons1, Comparator.comparing(Person::getFname));
System.out.println("Person1 (Sorted by first name): ");
for (Person p : persons1) {
System.out.println(p);
}
System.out.println();
// 依據First Name的長度排序
Arrays.sort(persons2, Comparator.comparing(Person::getFname, Comparator.comparingInt(String::length)));
System.out.println("Person2 (Sorted by length of first name):");
for (Person p : persons2) {
System.out.println(p);
}
}
}
② 靜態方法comparingXXX()
comparingInt()
comparingDouble()
comparingLong()
與comparing
是一樣的思路,只不過comparingXXX()
將comparing
中的提取出來的key
類型固定為了XXX
:
public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
}
③ 默認方法thenComparing()
thenComparing
是默認方法,需要對具體的Comparator
對象調用,它用於將多個Comparator
結合起來實現“鏈式的比較”:先根據XXX比較,再根據XXX比較,...
// 源碼
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
public class thenComparingDemo {
public static void main(String[] args) {
Person p1 = new Person("Alice", "Jessy");
Person p2 = new Person("Alice", "Ann");
Person p3 = new Person("Tom", "Smith");
Person[] persons = {p1, p2, p3};
// 先根據first name比較,再根據last name的長度比較
Comparator<Person> chainedComparator = Comparator.comparing(Person::getFname)
.thenComparing((x, y) -> (x.getLname().length() - y.getLname().length()));
// 先根據first name排序,再根據last name的長度排序
Arrays.sort(persons, chainedComparator);
for (Person p : persons) {
System.out.println(p);
}
}
}
/*
Alice Ann
Alice Jessy
Tom Smith
參考:
https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#thenComparing-java.util.Comparator
Java Comparator接口學習筆記