Java Map.replaceAll: normalize ค่าใน map โดยรักษาชุด key เดิม
เมื่อ config map มี key ถูกต้องอยู่แล้วแต่ value ต้อง trim และ normalize การสร้าง loop พร้อม put ซ้ำทำให้โค้ดดูเหมือนแก้โครงสร้าง map Map.replaceAll สื่อชัดว่าแปลงค่าของทุก entry โดยรักษาชุด key เดิมครับ
WHY: เปลี่ยนของในขวด ไม่ย้ายชั้นวาง
เราต้องการล้างฉลากและปรับรูปแบบค่า ไม่ได้เพิ่มหรือลบช่อง การใช้ operation ที่ตรงเจตนาช่วยให้ reviewer มองเห็น boundary ว่า key set ต้องคงเดิม
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class Main {
static void normalize(Map<String, String> values) {
values.replaceAll((key, value) -> {
if (value == null) throw new IllegalArgumentException("null value for " + key);
return value.trim().toLowerCase(Locale.ROOT);
});
}
public static void main(String[] args) {
Map<String, String> config = new HashMap<>();
config.put("MODE", " Strict ");
config.put("REGION", " TH ");
normalize(config);
assert config.equals(Map.of("MODE", "strict", "REGION", "th"));
assert config.keySet().equals(Map.of("MODE", "", "REGION", "").keySet());
System.out.println("replaceAll normalization verified");
}
}
HOW: การเปลี่ยนหลาย entry ไม่ใช่ transaction
ถ้า BiFunction โยน exception หลังแปลงบาง entry ไปแล้ว map อาจอยู่ในสถานะครึ่งเก่าครึ่งใหม่ สำหรับข้อมูลสำคัญให้สร้าง map ใหม่ ตรวจครบ แล้วค่อยสลับ reference หรือ commit ผ่าน transaction replaceAll เหมาะเมื่อ function เชื่อถือได้และ mutation ระหว่างทางยอมรับได้
Map บางชนิดไม่รองรับการแก้ค่า และ implementation concurrent อาจมี atomicity ต่อ entry ต่างจากทั้ง map อย่าสมมติว่าผู้อ่าน thread อื่นจะเห็น snapshot เดียวกัน ควร validate null และรูปแบบ input ก่อนเริ่ม รวมทั้งใช้ Locale.ROOT กับ identifier ที่ไม่ใช่ภาษามนุษย์เพื่อเลี่ยง case mapping ตาม locale เครื่อง
Recap
- ใช้
replaceAllเมื่อชุด key ต้องคงเดิม - validate input ก่อน mutation ถ้าห้ามมี partial update
- อย่าสมมติ atomic ทั้ง map
- ระบุ null policy และ locale ชัดเจน
- ใช้ copy-then-swap สำหรับ config สำคัญ