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

การ Implement เมธอดของ Stream API ใน Java 9

Stream API ให้ built-in functionality มากมายช่วยดำเนินการบน collection ด้วย stream pipeline API เป็น declarative programming ทำให้โค้ด precise และ less error-prone ใน Java 9 เพิ่มเมธอดที่มีประโยชน์ให้ Stream API

เมธอดใหม่ใน Java 9

  • Stream.iterate(): Stream version replacement สำหรับ traditional for-loops
  • Stream.takeWhile(): ใช้ใน while loop ที่ takes value ขณะที่ condition เป็นจริง
  • Stream.dropWhile(): ใช้ใน while loop ที่ drops value ขณะที่ condition เป็นจริง

ตัวอย่างโค้ด


import java.util.Arrays;
import java.util.Iterator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamAPITest {
    public static void main(String args[]) {
        String[] sortedNames = {"Adithya", "Bharath", "Charan", "Dinesh", "Raja", "Ravi", "Zaheer"};
        
        System.out.println("[Traditional for loop] Indexes of names starting with R = ");
        for(int i = 0; i < sortedNames.length; i++) {
            if(sortedNames[i].startsWith("R")) {
                System.out.println(i);
            }
        }
        
        System.out.println("[Stream.iterate] Indexes of names starting with R = ");
        Stream.iterate(0, i -> i < sortedNames.length, i -> ++i)
            .filter(i -> sortedNames[i].startsWith("R"))
            .forEach(System.out::println);
        
        String namesAtoC = Arrays.stream(sortedNames)
            .takeWhile(n -> n.charAt(0) <= 'C')
            .collect(Collectors.joining(","));
        
        String namesDtoZ = Arrays.stream(sortedNames)
            .dropWhile(n -> n.charAt(0) <= 'C')
            .collect(Collectors.joining(","));
        
        System.out.println("Names A to C = " + namesAtoC);
        System.out.println("Names D to Z = " + namesDtoZ);
    }
}

ผลลัพธ์


[Traditional for loop] Indexes of names starting with R = 
4
5
[Stream.iterate] Indexes of names starting with R = 
4
5
Names A to C = Adithya,Bharath,Charan
Names D to Z = Dinesh,Raja,Ravi,Zaheer

คำอธิบายเมธอดใหม่

Stream.iterate(seed, hasNext, next)


// ตัวแปร seed, predicate hasNext, function next
Stream.iterate(0, i -> i < 10, i -> i + 1)  // 0,1,2,3,4,5,6,7,8,9
Stream.iterate(1, i -> i <= 100, i -> i * 2) // 1,2,4,8,16,32,64

แทน for loop: for (int i = seed; hasNext.test(i); i = next.apply(i))

takeWhile(Predicate)


// รับ elements ตราบใดที่ predicate true
Stream.of(1,2,3,4,5).takeWhile(n -> n < 4)  // 1,2,3
Stream.of("a","ab","abc","abcd").takeWhile(s -> s.length() < 3) // "a","ab"

dropWhile(Predicate)


// ข้าม elements ตราบใดที่ predicate true แล้วรับที่เหลือ
Stream.of(1,2,3,4,5).dropWhile(n -> n < 4)  // 4,5
Stream.of("a","ab","abc","abcd").dropWhile(s -> s.length() < 3) // "abc","abcd"

เปรียบเทียบ: Iterate vs TakeWhile/DropWhile

Method Input Behavior Termination
iterate(seed, pred, next) Seed value Generate infinite stream When pred returns false
takeWhile(pred) Existing stream Take prefix while true First false (short-circuit)
dropWhile(pred) Existing stream Drop prefix while true First false (then take all)

Java 8 iterate() vs Java 9 iterate()


// Java 8 - infinite stream, ต้อง limit เอง
Stream.iterate(0, i -> i + 1).limit(10).forEach(System.out::println);

// Java 9 - มี predicate termination built-in
Stream.iterate(0, i -> i < 10, i -> i + 1).forEach(System.out::println);

Practical Example: Pagination


// takeWhile สำหรับ pagination
Stream.iterate(0, page -> page < totalPages, page -> page + 1)
    .flatMap(page -> fetchPage(page).stream())
    .takeWhile(items -> !items.isEmpty())
    .forEach(processItem);

// dropWhile สำหรับ skip header
Files.lines(Paths.get("data.csv"))
    .dropWhile(line -> line.startsWith("#"))  // skip comments
    .skip(1)  // skip header
    .map(CSVParser::parse)
    .forEach(processRecord);