นากกายต้นฉบับกำลังคัดเม็ดข้อมูลจากกรวยสแกนเนอร์ลงราง stream บนโต๊ะสว่าง

Java Scanner.tokens: เปลี่ยน token stream เป็น pipeline ที่ปิด resource ชัดเจน

พี่โชว์Engineering

Scanner.tokens() เปิด token ที่ scanner แยกไว้เป็น Stream<String> เราจึงต่อ map, filter และ collector ได้โดยไม่เขียน while loop ครับ แต่ stream ยังผูกกับ scanner และ input เดิม ต้อง consume ภายในช่วงที่ resource เปิดอยู่

import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        try (var scanner = new Scanner("mint, forest, , teal")) {
            scanner.useDelimiter("\\s*,\\s*");
            List<String> colors = scanner.tokens()
                    .map(String::trim)
                    .filter(token -> !token.isEmpty())
                    .toList();
            assert colors.equals(List.of("mint", "forest", "teal"));
        }

        try (var scanner = new Scanner("")) {
            assert scanner.tokens().count() == 0;
        }
    }
}

Tokenizer เล็ก ไม่ใช่ CSV parser เต็มรูปแบบ

Delimiter regex ไม่เข้าใจ quoted comma, escape และ newline ใน field หากข้อมูลเป็น CSV จริงให้ใช้ parser ที่รองรับมาตรฐาน อย่าขยาย regex จนกลายเป็นร้านข้าวที่พยายามทำบัญชีภาษีด้วยกระดาษจดออเดอร์

Stream ต้องไม่ถูกใช้หลัง scanner ปิด และไม่ควรสร้าง parallel stream จาก scanner ที่อ่าน state ต่อเนื่อง หากต้องประมวลผลขนาน ให้ materialize token ที่ตรวจแล้วก่อน

Recap

  • consume stream ภายใน try-with-resources
  • กำหนด delimiter ให้ตรง format ง่าย ๆ เท่านั้น
  • ใช้ parser เฉพาะทางสำหรับ CSV/grammar จริง
  • อย่าใช้ stream หลัง scanner ถูกปิด