นากแม่น้ำสีมิ้นต์ต้นฉบับกำลังพลิกป้ายกรองเชิงภาพเพื่อแยกตะกร้าว่างออกจากตะกร้าที่มีของ

Java Predicate.not: ปฏิเสธเงื่อนไขโดยยังอ่านเป็นประโยค

พี่โชว์Engineering

filter(value -> !value.isBlank()) ใช้งานได้ แต่เมื่อเงื่อนไขเป็น method reference เรามักต้องกลับไปเขียน lambda เพียงเพื่อใส่ ! ครับ Predicate.not ทำให้ประโยค “กรองสิ่งที่ไม่ blank” ยังเห็นชื่อ method ตรง ๆ

import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

public class Main {
  public static void main(String[] args) {
    List<String> raw = List.of("forest", " ", "amber", "");
    List<String> cleaned = raw.stream()
        .filter(Predicate.not(String::isBlank))
        .toList();

    assert cleaned.equals(List.of("forest", "amber")) : cleaned;

    Predicate<String> nonNull = Objects::nonNull;
    Predicate<String> useful = nonNull.and(Predicate.not(String::isBlank));
    assert useful.test("mint");
    assert !useful.test(null);
  }
}

อ่านง่ายไม่ได้แปลว่าครอบทุก edge case

Predicate.not รับ predicate ที่ไม่เป็น null แต่ predicate ข้างในยังอาจ throw เมื่อค่าที่ส่งเข้าเป็น null การต่อ Objects::nonNull ด้วย and ปลอดภัยเพราะ short-circuit จากซ้ายไปขวา ตั้งชื่อ predicate ตาม domain เมื่อเงื่อนไขยาวกว่าเมธอดเดียว จะอ่านง่ายกว่าซ้อน not, and, or หลายชั้น

Recap

  • ใช้ Predicate.not เพื่อรักษา method reference ที่อ่านง่าย
  • วาง null guard ไว้ซ้ายสุดของ and
  • ตั้งชื่อ predicate เมื่อ business rule เริ่มยาว
  • ทดสอบ blank, empty และ null ตาม policy จริง