flatMap สำหรับคอลเลกชันแบบซ้อน
ทำรายการซ้อน, สายโซ่ Optional และโครงสร้างไฟล์กับบรรทัดให้แบนราบด้วย flatMap
flatMap สำหรับคอลเลกชันแบบซ้อน เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
ปัญหาคอลเลกชันซ้อนกัน
เมื่อแต่ละองค์ประกอบของสตรีมถูกแปลงเป็นคอลเลกชันอื่น map จะให้ผลลัพธ์เป็น Stream<List<T>> ส่วน flatMap จะรวมสตรีมภายในให้เป็น Stream<T> แบบแบนหนึ่งชุด
List<List<Integer>> nested = List.of(List.of(1,2), List.of(3,4), List.of(5));
// With map:
Stream<List<Integer>> s = nested.stream().map(l -> l); // Stream<List<Integer>>
// With flatMap:
Stream<Integer> flat = nested.stream().flatMap(List::stream); // Stream<Integer>
flat.forEach(System.out::println); // 1 2 3 4 5flatMap เทียบกับ map
map(f) ใช้ f กับแต่ละองค์ประกอบและห่อผลลัพธ์ไว้ ส่วน flatMap(f) ใช้ f ซึ่งคืนค่าสตรีม แล้วนำสตรีมทั้งหมดเหล่านั้นมาต่อกันเป็นสตรีมเดียว
// map: List<String> -> Stream<Stream<Character>>
Stream<Stream<Character>> nested = List.of("hi","bye").stream()
.map(s -> s.chars().mapToObj(c -> (char)c));
// flatMap: List<String> -> Stream<Character>
Stream<Character> flat = List.of("hi","bye").stream()
.flatMap(s -> s.chars().mapToObj(c -> (char)c));การทำให้คำสั่งซื้อและรายการสินค้าเป็นสตรีมแบบแบน
กรณีใช้งานที่พบบ่อย: คำสั่งซื้อแต่ละรายการมีรายการสินค้าเป็นลิสต์ ให้สร้างสตรีมแบบแบนที่มีรายการสินค้าทั้งหมดจากทุกคำสั่งซื้อ
List<String> allItems = orders.stream()
.flatMap(order -> order.getItems().stream())
.collect(Collectors.toList());
System.out.println(allItems);flatMap กับ Optional
ใช้ stream() กับ Optional (Java 9 ขึ้นไป) เพื่อแปลงเป็นสตรีมที่มี 0 หรือ 1 องค์ประกอบ จากนั้น flatMap จะยุบ Stream<Optional<T>> ให้เป็น Stream<T>
List<Optional<String>> maybes = List.of(Optional.of("a"), Optional.empty(), Optional.of("c"));
List<String> values = maybes.stream()
.flatMap(Optional::stream) // Java 9+
.collect(Collectors.toList());
System.out.println(values); // [a, c]การอ่านทุกบรรทัดจากหลายไฟล์
flatMap ช่วยให้ต่อทุกบรรทัดจากรายการไฟล์ให้เป็นสตรีมเดียวได้ง่าย โดยไม่ต้องใช้ลูปซ้อนกัน
List<Path> files = List.of(Path.of("a.txt"), Path.of("b.txt"));
List<String> allLines = files.stream()
.flatMap(p -> {
try { return Files.lines(p); }
catch (IOException e) { return Stream.empty(); }
})
.collect(Collectors.toList());การแยกสตริงเป็นคำ
แยกแต่ละประโยคเป็นคำ แล้วทำให้คำทั้งหมดเป็นสตรีมเดียวเพื่อใช้การนับความถี่ของคำ
List<String> sentences = List.of("hello world", "java streams rock");
Map<String, Long> freq = sentences.stream()
.flatMap(s -> Arrays.stream(s.split("\\s+")))
.collect(Collectors.groupingBy(w -> w, Collectors.counting()));
System.out.println(freq);flatMap กับ Map.entrySet
ทำให้แมปของหมวดหมู่ที่ชี้ไปยังลิสต์รายการสินค้าเป็นสตรีมของรายการสินค้าทั้งหมด
Map<String, List<String>> catalog = Map.of(
"fruit", List.of("apple","banana"),
"veg", List.of("carrot","pea"));
List<String> all = catalog.values().stream()
.flatMap(List::stream)
.sorted()
.collect(Collectors.toList());
System.out.println(all); // [apple, banana, carrot, pea]การหลีกเลี่ยง NullPointerException ใน flatMap
หากฟังก์ชันอาจคืนค่า null แทนสตรีม ให้ตรวจสอบค่า null หรือคืนค่า Stream.empty() เพื่อหลีกเลี่ยง NullPointerException
departments.stream()
.flatMap(dept -> dept.getEmployees() == null
? Stream.empty()
: dept.getEmployees().stream())
.forEach(System.out::println);การนับคำที่ไม่ซ้ำด้วย flatMap
ใช้ flatMap, distinct และ count ร่วมกันเพื่อประมวลผลข้อมูลอย่างกระชับ
long distinctWords = sentences.stream()
.flatMap(s -> Arrays.stream(s.toLowerCase().split("[^a-z]+")))
.filter(w -> !w.isEmpty())
.distinct()
.count();
System.out.println("Distinct: " + distinctWords);flatMapToInt สำหรับสตรีมชนิดข้อมูลพื้นฐาน
ใช้ flatMapToInt, flatMapToLong และ flatMapToDouble เพื่อหลีกเลี่ยงการห่อชนิดเมื่อทำให้เป็นสตรีมของชนิดข้อมูลพื้นฐาน
int totalQuantity = orders.stream()
.flatMapToInt(order -> order.getItems().stream().mapToInt(Item::getQuantity))
.sum();
System.out.println("Total qty: " + totalQuantity);หมายเหตุด้านประสิทธิภาพ
การเรียก flatMap แต่ละครั้งจะเพิ่มชั้นของสตรีม สำหรับชุดข้อมูลขนาดใหญ่มากที่มีคอลเลกชันภายในขนาดเล็กจำนวนมาก ควรพิจารณาวิธีแบบวนซ้ำหรือ Spliterator เพื่อลดค่าใช้จ่ายในการสร้างออบเจ็กต์
ตรวจสอบอย่างรวดเร็ว
flatMap ทำสิ่งใดแตกต่างจาก map
สรุปทบทวน
flatMap แปลงแต่ละองค์ประกอบเป็นสตรีมแล้วรวมสตรีมทั้งหมดเป็นหนึ่งเดียว ใช้เพื่อทำให้คอลเลกชันที่ซ้อนกันเป็นแบบแบน เชื่อมต่อ Optional แยกสตริง และอ่านหลายไฟล์ ใช้ flatMapToInt เพื่อหลีกเลี่ยงการห่อชนิด
คำถามที่พบบ่อย
บทเรียน “flatMap สำหรับคอลเลกชันแบบซ้อน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “flatMap สำหรับคอลเลกชันแบบซ้อน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “flatMap สำหรับคอลเลกชันแบบซ้อน”
ทำรายการซ้อน, สายโซ่ Optional และโครงสร้างไฟล์กับบรรทัดให้แบนราบด้วย flatMap คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “flatMap สำหรับคอลเลกชันแบบซ้อน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- flatMap สำหรับคอลเลกชันแบบซ้อน
- สตรีมแบบขนาน: ประสิทธิภาพและข้อควรระวัง
- Spliterator: การแบ่งเพื่อการทำงานแบบขนาน
- สตรีมไม่สิ้นสุดด้วย iterate และ generate