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 จริง