Java removeIf: ล้างสมาชิกใน collection โดยไม่แก้ระหว่าง for-each
การลบสมาชิกจาก collection ภายใน enhanced for มักจบด้วย ConcurrentModificationException Collection.removeIf รวมเงื่อนไขกับการลบผ่าน iterator ของ collection อย่างถูกสัญญา เหมาะกับการ cleanup แบบ in-place ครับ
WHY: ให้ตะกร้าจัดการช่องว่างเอง
เหมือนคัดผลไม้ช้ำออกจากตะกร้า เราบอกเกณฑ์ว่าใบไหนต้องออก ส่วนตะกร้ารับผิดชอบการเลื่อนของที่เหลือ ไม่ควรดึงของออกระหว่างเดินนับด้วยกลไกคนละชุด
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class Main {
record Coupon(String code, LocalDate expiresOn) {}
static int removeExpired(List<Coupon> coupons, LocalDate today) {
int before = coupons.size();
coupons.removeIf(coupon -> coupon.expiresOn().isBefore(today));
return before - coupons.size();
}
public static void main(String[] args) {
List<Coupon> coupons = new ArrayList<>(List.of(
new Coupon("OLD", LocalDate.of(2026, 10, 11)),
new Coupon("TODAY", LocalDate.of(2026, 10, 12)),
new Coupon("NEXT", LocalDate.of(2026, 10, 13))
));
assert removeExpired(coupons, LocalDate.of(2026, 10, 12)) == 1;
assert coupons.stream().map(Coupon::code).toList().equals(List.of("TODAY", "NEXT"));
assert removeExpired(coupons, LocalDate.of(2026, 10, 12)) == 0;
System.out.println("removeIf cleanup verified");
}
}
HOW: API นี้แก้ collection เดิม
removeIf คืน true เมื่อมีสมาชิกถูกลบ แต่ไม่ได้คืนรายการที่หายไป ตัวอย่างนับขนาดก่อนและหลัง ถ้าต้อง audit รายการที่ลบ ให้ snapshot เฉพาะรายการนั้นก่อน หรือออกแบบ operation ให้ repository บันทึก event พร้อม transaction
Collection ต้องรองรับ mutation เช่น new ArrayList<>(...); List.of(...) โดยตรงเป็น immutable และจะโยน UnsupportedOperationException เมื่อมีสมาชิกต้องลบ Predicate ควรไม่มี side effect เพราะ implementation อาจมีพฤติกรรม iteration ต่างกัน และห้ามแก้ collection เดียวกันจาก thread อื่นโดยไม่มี synchronization
Recap
- ใช้
removeIfแทนลบจาก enhanced for-loop - ยืนยันว่า collection mutable
- ทำ predicate ให้บริสุทธิ์และรวดเร็ว
- เก็บ audit ก่อนลบถ้าต้องรู้รายการที่หาย
- ทดสอบ boundary เช่นหมดอายุ “ก่อนวันนี้” กับ “วันนี้”