นากกายต้นฉบับเรียงบัตรชื่อบนราง โดยบัตรว่างถูกเลื่อนไปช่องสุดท้ายสีอำพัน

Java Comparator.nullsLast: วางค่าที่หายไว้ท้ายตารางโดยไม่เขียน if ซ้อน

พี่โชว์Engineering

หน้ารายงานที่เรียงตาม owner มักมีรายการยังไม่ถูก assign ถ้าใช้ natural order ตรง ๆ ค่า null จะทำให้ sort ล้มทั้งชุด Comparator.nullsLast ห่อ comparator ปกติแล้วกำหนดว่า null มากกว่าค่าอื่น จึงไปอยู่ท้ายผลลัพธ์โดยไม่ต้องเขียนเงื่อนไขหลายชั้นครับ

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Main {
    record Ticket(String owner, int priority) {}

    static List<Ticket> ordered(List<Ticket> input) {
        var result = new ArrayList<>(input);
        var byOwner = Comparator.comparing(
            Ticket::owner,
            Comparator.nullsLast(Comparator.naturalOrder())
        );
        result.sort(byOwner.thenComparingInt(Ticket::priority));
        return result;
    }

    public static void main(String[] args) {
        var sorted = ordered(List.of(
            new Ticket("mai", 2),
            new Ticket(null, 1),
            new Ticket("an", 3),
            new Ticket("an", 1)
        ));
        assert sorted.get(0).equals(new Ticket("an", 1));
        assert sorted.get(1).equals(new Ticket("an", 3));
        assert sorted.get(3).owner() == null;
    }
}

nullsFirst และ nullsLast อธิบายนโยบายตำแหน่ง ไม่ได้แก้ปัญหาคุณภาพข้อมูล ถ้า owner เป็นฟิลด์บังคับ null ควรถูก reject ตอนรับข้อมูล ไม่ใช่จัดไว้ท้ายตารางแล้วลืมมัน แต่ถ้า null หมายถึง “ยังไม่ assign” อย่างถูกต้อง comparator นี้ทำให้สถานะนั้นชัดในจุดแสดงผล

เมื่อกลับลำดับต้องระวัง .reversed() เพราะมันกลับทั้ง comparator รวมถึงตำแหน่ง null หากต้องการชื่อ Z→A แต่ยังให้ null อยู่ท้าย ให้กลับเฉพาะ comparator ด้านในแล้วค่อยห่อด้วย nullsLast การประกอบจากด้านในออกมาทำให้อ่าน policy ได้ตรงกว่า

Recap

  • ตกลงก่อนว่า null เป็นสถานะจริงหรือข้อมูลผิด
  • ห่อ comparator ของค่าปกติด้วย nullsLast
  • ต่อ tie-breaker เพื่อให้ผลลัพธ์ deterministic
  • กลับทิศ comparator ด้านในเมื่อ null ต้องอยู่ท้ายเหมือนเดิม