【JDK8】排序策略的實作
|
前情 << 【JDK8】從 synchronized、Lock 到 StampedLock 在收集物件之後,對物件進行排序是常用的動作,JDK8 之前,基本上可使用 搭配 Lambda 來排序如果你使用 JDK8,因為 List<String> words = Arrays.asList("B", "X", "A", "M", "F", "W", "O");
Collections.sort(words, (s1, s2) -> -s1.compareTo(s2));
List 的 sort 與 Stream 的 sorted實際上,JDK8 在 List<String> words = Arrays.asList("B", "X", "A", "M", "F", "W", "O");
words.sort((s1, s2) -> -s1.compareTo(s2));
如果只是想使用 List<String> words = Arrays.asList("B", "X", "A", "M", "F", "W", "O");
words.sort(String::compareTo);
以上的排序,會直接在原有的 List<String> words = Arrays.asList("B", "X", "A", "M", "F", "W", "O")
.stream()
.sorted()
.collect(toList());
在管線化操作時若使用 附帶一提的是, Comparator 的靜態方法JDK8 中,介面上也可以定義靜態方法, public class NullFirstStrLengthComparator implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
if(s1 == null) {
return -1;
}
if(s2 == null) {
return 1;
}
if(s1.length() == s2.length()) {
return 0;
}
if(s1.length() > s2.length()) {
return -1;
}
return 1;
}
}
不怎麼好讀,對吧!更別說為了表示這個比較器的目的,必須取個又臭又長的類別名稱!其實排序會有各式各樣的組合需求,JDK8 考量到這點,為排序加入了一些高階語義 API,例如 以方才的需求為例,在 JDK8 中要建立對應的 package cc.openhome;
import java.util.*;
import static java.util.Comparator.*;
import static java.lang.System.out;
public class Sort6 {
public static void main(String[] args) {
List words = Arrays.asList(
"B", "X", "A", "M", null ,"F", "W", "O", null);
Collections.sort(words, nullsFirst(comparingInt(String::length)));
out.println(words); // [null, null, X, W, O, M, F, B, A]
}
}
Comparator 的預設方法JDK8 中,介面上也可以定義預設方法(Default method),實際上, 例如,你可能想要排序時先依客戶的姓來排,如果姓相同再依名來排,如果姓名都相同,再依他們居住地的郵遞區號來排,那麼你可以如下建立 package cc.openhome;
import static java.lang.System.out;
import java.util.*;
import static java.util.Comparator.comparing;
public class CustomerDemo {
public static void main(String[] args) {
List<Customer> customers = Arrays.asList(
new Customer("Justin", "Lin", 804),
new Customer("Monica", "Huang", 804),
new Customer("Irene", "Lin", 804)
);
Comparator<Customer> byLastName = comparing(Customer::getLastName);
customers.sort(
byLastName
.thenComparing(Customer::getFirstName)
.thenComparing(Customer::getZipCode)
);
customers.forEach(out::println);
}
}
class Customer {
private String firstName;
private String lastName;
private Integer zipCode;
public Customer(String firstName, String lastName, Integer zipCode) {
this.firstName = firstName;
this.lastName = lastName;
this.zipCode = zipCode;
}
public String toString() {
return String.format("Customer(%s %s, %d)", firstName, lastName, zipCode);
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public Integer getZipCode() { return zipCode; }
}
每次 如果你沒有使用 JDK8,基本上在 guava-libraries 上,也可以取得這類高階排序 API,這部份的內容可以參考 【Guava 教學】(3)高階排序概念的實現。 |

Java 學習之路




