網頁

2020/5/29

Java 排序比較兩個可能有null的欄位 sorted by two fields with null

Java排序List時,若排序元素的屬性可能為null,則可以在Comparator的實作中處理null。

例如下面是List中的元素Employee

Employee

public class Employee {

    private String name;
    private Integer age;

    // getters and setters

    public String toString() {
        return String.format("name=%s, age=%d", name, age);
    }
}

使用下面的靜態方法compare()來處理null。第一及第二個參數為比較對像,第三個boolean參數決定null要排前面還是排後面。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {

        List employeeList = Arrays.asList(
                new Employee("mary", 22),
                new Employee("john", 16),
                new Employee(null, 34),
                new Employee("alice", null));

        employeeList = employeeList.stream().sorted((o1, o2) -> {
            int result = compare(o1.getName(), o2.getName(), true);
            if (result != 0) {
                return result;
            }
            result = compare(o1.getAge(), o2.getAge(), false);
            return result;
        }).collect(Collectors.toList());

        employeeList.forEach(System.out::println);
        /*
        name=null, age=34
        name=alice, age=null
        name=john, age=16
        name=mary, age=22
         */

    }

    public static <T extends Comparable<T>> int compare(T a, T b, boolean nullFirst) {
        if (a == null) {
            return (b == null) ? 0 : (nullFirst ? -1 : 1);
        } else if (b == null) {
            return nullFirst ? 1: -1;
        } else {
            return a.compareTo(b);
        }
    }

}

或是用Comparator.nullFirst()Comparator.nullLast()來達到更lambda的寫法。

employeeList = employeeList.stream()
        .sorted(Comparator
                .comparing(Employee::getName, Comparator.nullsFirst(Comparator.naturalOrder()))
                .thenComparing(Employee::getAge, Comparator.nullsLast(Comparator.naturalOrder())))
        .collect(Collectors.toList());

沒有留言:

張貼留言