นากกายต้นฉบับกำลังเปิดบานแยกรางให้ลูกแก้วบางลูกผ่านออกมาหลายลูกและบางช่องไม่ปล่อยอะไร

Java Stream.mapMulti: คืนศูนย์หรือหลายผลลัพธ์โดยไม่สร้าง Stream ย่อยทุกครั้ง

พี่โชว์Engineering

flatMap เหมาะเมื่อแต่ละ input มี collection หรือ stream ย่อยอยู่แล้ว แต่ถ้าเราต้อง “คืนศูนย์หรือหนึ่งค่า” หลัง validation การสร้าง Stream.empty() กับ Stream.of() ทุกครั้งทำให้ใจความถูกซ่อน Stream.mapMulti ให้ callback ส่งผลลัพธ์เข้า consumer เท่าที่ต้องการ จึงไม่ต้องสร้าง stream ย่อยครับ

import java.util.List;

public class Main {
    static List<Integer> positiveIntegers(List<String> values) {
        return values.stream().<Integer>mapMulti((value, out) -> {
            try {
                int parsed = Integer.parseInt(value);
                if (parsed > 0) out.accept(parsed);
            } catch (NumberFormatException ignored) {
                // invalid input emits zero values
            }
        }).toList();
    }

    public static void main(String[] args) {
        assert positiveIntegers(List.of("4", "bad", "-2", "7"))
                .equals(List.of(4, 7));
        assert positiveIntegers(List.of()).isEmpty();
        System.out.println("mapMulti tests passed");
    }
}

mapMulti ยังคืนหลายค่าได้ด้วยการเรียก out.accept() หลายครั้ง แต่ถ้า callback ยาวจนกลายเป็น parser เต็มตัว ควรย้าย logic ไปเมธอดที่มีชื่อเพื่อรักษาความอ่านง่าย การกลืน exception ในตัวอย่างเหมาะเพราะสัญญาคือคัดค่าที่ parse ไม่ได้ออก หากระบบต้องรายงาน input เสียควรใช้ result type หรือเก็บ error แยก ไม่ใช่ทำให้ข้อมูลหายเงียบ ๆ

Recap

  • ใช้เมื่อหนึ่ง input ให้ผลศูนย์ หนึ่ง หรือหลายค่า
  • เลือก flatMap ถ้ามี stream ย่อยอยู่แล้ว
  • อย่ากลืน parse error หากสัญญาต้องรายงานผู้ใช้
  • ระบุ type witness เมื่อ compiler infer ชนิดผลไม่ชัด