Java String.lines: อ่านข้อความหลายบรรทัดแบบ Stream โดยไม่ทิ้งท้ายด้วยช่องว่างปลอม
การแยกข้อความด้วย split("\\R") เรียก regex engine และมี semantics เรื่องช่องว่างท้ายที่ต้องจำ String.lines() คืน lazy Stream<String> สำหรับบรรทัดที่คั่นด้วย \n, \r หรือ \r\n และไม่สร้างบรรทัดว่างเพิ่มเพียงเพราะข้อความจบด้วย line terminator
import java.util.List;
public class Main {
static List<String> nonBlankLines(String text) {
return text.lines()
.map(String::strip)
.filter(line -> !line.isEmpty())
.toList();
}
public static void main(String[] args) {
String mixed = " first\r\n\r\nsecond \n";
assert nonBlankLines(mixed).equals(List.of("first", "second"));
assert "".lines().count() == 0;
assert "one\n".lines().toList().equals(List.of("one"));
System.out.println("String.lines tests passed");
}
}
เมื่อไหร่ยังต้องใช้วิธีอื่น
lines() เหมาะกับ text processing ที่นิยามบรรทัดแบบ Java แต่ไม่ได้คืนตัวคั่น หากต้องรักษา newline เดิมเพื่อ formatter หรือ patch tool ให้ parser เก็บ delimiter เอง และถ้าต้องอ่านไฟล์ใหญ่ อย่าโหลดทั้งหมดมาเป็น String ก่อน ใช้ Files.lines(path) ภายใน try-with-resources เพื่อปิดไฟล์ให้แน่นอน
Stream นี้ lazy ในระดับการแยกบรรทัดของ String ที่อยู่ในหน่วยความจำแล้ว จึงช่วยลด array ชั่วคราวจาก split() แต่ไม่ได้ทำให้ String ต้นทางเล็กลง
Recap
- ใช้
String.lines()เมื่อมี String อยู่แล้วและต้อง process เป็น Stream - จำว่า newline ท้ายสุดไม่สร้างบรรทัดว่างเพิ่ม
- ใช้
Files.lines()สำหรับไฟล์ใหญ่และปิด resource - ใช้ parser อื่นเมื่อจำเป็นต้องรักษาตัวคั่นเดิม