Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

ความแตกต่างระหว่าง Intermediate และ Terminal Operations ใน Java 8 Stream

ความแตกต่างระหว่าง Intermediate และ Terminal Operations ใน Java 8 Stream API

Stream API ใน Java 8 ใช้สำหรับประมวลผลข้อมูลแบบ Declarative (บอกว่าทำอะไร ไม่ใช่ทำอย่างไร) Operations แบ่งเป็น 2 ประเภทหลัก

Intermediate Operations (ออปเรชันกลาง)

  • เปลี่ยน Stream หนึ่งเป็นอีก Stream หนึ่ง (Pipeline)
  • Lazy Evaluation: ไม่ทำงานทันที รอ Terminal Operation
  • สามารถ Chain ได้หลายตัวต่อเนื่อง
  • คืนค่า Stream<T>

ตัวอย่าง Intermediate Operations

  • แปลงองค์ประกอบแต่ละตัว
  • เมธอด คำอธิบาย
    filter(Predicate) กรององค์ประกอบตามเงื่อนไข
    map(Function)
    flatMap(Function) แบน (flatten) nested streams
    distinct() ลบซ้ำ (ใช้ equals/hashCode)
    sorted() / sorted(Comparator) เรียงลำดับ
    peek(Consumer) ดูค่าแต่ละตัว (debug/logging)
    limit(n) จำกัดจำนวน n ตัวแรก
    skip(n) ข้าม n ตัวแรก

    Terminal Operations (ออปเรชันปลายทาง)

    • ผลิตผลลัพธ์สุดท้าย (Result) หรือ Side-effect
    • Eager Evaluation: ทำงานทันที และจบ Stream pipeline
    • ไม่สามารถ Chain ต่อได้
    • คืนค่า Non-Stream (Collection, Primitive, void, Optional)

    ตัวอย่าง Terminal Operations

    เมธอด คำอธิบาย คืนค่า
    forEach(Consumer) วนลูปทำ side-effect void
    collect(Collector) รวบรวมเป็น Collection Collection/List/Set/Map
    toArray() แปลงเป็น Array Object[] / T[]
    reduce() ลดรูปเป็นค่าเดียว Optional / T
    count() นับจำนวน long
    min()/max(Comparator) หาค่าต่ำสุด/สูงสุด Optional
    anyMatch/allMatch/noneMatch ตรวจสอบเงื่อนไข boolean
    findFirst()/findAny() หาตัวแรก/ตัวไหนก็ได้ Optional

    ตารางเปรียบเทียบ

    คุณสมบัติ Intermediate Terminal
    การทำงาน Lazy (รอ Terminal) Eager (ทันที)
    คืนค่า Stream<T> Non-Stream (Result)
    Chain ได้ ✅ ได้หลายตัว ❌ จบ Pipeline
    Short-circuit บางตัว (limit, findFirst) บางตัว (anyMatch, findFirst)

    ตัวอย่าง Pipeline สมบูรณ์

    import java.util.*;
    import java.util.stream.*;
    
    public class StreamDemo {
        public static void main(String[] args) {
            List laptops = Arrays.asList("DELL", "ACER", "HCL", "ASUS", "LENOVO");
            
            // Pipeline: Intermediate -> Intermediate -> Terminal
            List result = laptops.stream()
                .filter(s -> s.length() > 3)        // Intermediate: filter
                .map(String::toLowerCase)           // Intermediate: transform
                .sorted()                           // Intermediate: sort
                .peek(s -> System.out.println("Processing: " + s)) // Intermediate: peek
                .collect(Collectors.toList());      // Terminal: collect
            
            System.out.println("Result: " + result);
        }
    }

    ผลลัพธ์

    Processing: acer
    Processing: asus
    Processing: dell
    Processing: hcl
    Processing: lenovo
    Result: [acer, asus, dell, hcl, lenovo]

    ข้อสังเกตสำคัญ

    • Lazy Evaluation: Intermediate ops ไม่ทำงานจนกว่าจะมี Terminal op
    • Short-circuiting: limit(), findFirst() หยุดเร็วเมื่อได้ผล
    • Stateless vs Stateful: filter/map stateless (เร็ว), sorted/distinct stateful (ต้องดูทั้งหมด)
    • Parallel Streams: ใช้ .parallelStream() แทน .stream() สำหรับข้อมูลมาก