Java Stream API: ประมวลผลข้อมูลแบบ Functional

#java13 เม.ย. 2569

Stream API คืออะไร

Stream API (Java 8+) ช่วยให้ประมวลผล collections ด้วย functional style ทำให้โค้ดกระชับและอ่านง่ายขึ้นมาก

สร้าง Stream

import java.util.stream.*;
import java.util.*;

// จาก Collection
List<String> names = List.of("สมชาย", "สมหญิง", "สมศักดิ์", "สมใจ");
Stream<String> stream = names.stream();

// จาก Array
int[] numbers = {1, 2, 3, 4, 5};
IntStream intStream = Arrays.stream(numbers);

// Stream.of()
Stream<String> s = Stream.of("a", "b", "c");

// Infinite stream
Stream<Integer> infinite = Stream.iterate(0, n -> n + 1);

Intermediate Operations

List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// filter
List<Integer> evens = nums.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());
// [2, 4, 6, 8, 10]

// map
List<String> strings = nums.stream()
    .map(n -> "item-" + n)
    .collect(Collectors.toList());

// sorted
List<String> sorted = names.stream()
    .sorted()
    .collect(Collectors.toList());

// distinct
List<Integer> unique = List.of(1, 2, 2, 3, 3, 3).stream()
    .distinct()
    .collect(Collectors.toList());
// [1, 2, 3]

// limit และ skip
List<Integer> first3 = nums.stream().limit(3).collect(Collectors.toList());
List<Integer> skip3 = nums.stream().skip(3).collect(Collectors.toList());

Terminal Operations

// collect
List<Integer> list = nums.stream().filter(n -> n > 5).collect(Collectors.toList());
Set<Integer> set = nums.stream().collect(Collectors.toSet());
String joined = names.stream().collect(Collectors.joining(", "));

// reduce
int sum = nums.stream().reduce(0, Integer::sum);
Optional<Integer> max = nums.stream().reduce(Integer::max);

// count, min, max
long count = nums.stream().filter(n -> n > 5).count();
Optional<Integer> minimum = nums.stream().min(Integer::compareTo);

// forEach
nums.stream().forEach(System.out::println);

// anyMatch, allMatch, noneMatch
boolean hasEven = nums.stream().anyMatch(n -> n % 2 == 0);
boolean allPositive = nums.stream().allMatch(n -> n > 0);

Collectors

// groupingBy
Map<String, List<String>> byDept = employees.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment));

// counting
Map<String, Long> countByDept = employees.stream()
    .collect(Collectors.groupingBy(
        Employee::getDepartment,
        Collectors.counting()
    ));

// averagingDouble
Map<String, Double> avgSalaryByDept = employees.stream()
    .collect(Collectors.groupingBy(
        Employee::getDepartment,
        Collectors.averagingDouble(Employee::getSalary)
    ));

Parallel Stream

// ประมวลผลแบบ parallel
long sum = LongStream.rangeClosed(1, 1_000_000)
    .parallel()
    .sum();

สรุป

Stream API ทำให้โค้ดกระชับและอ่านง่ายขึ้นมาก เหมาะกับการ filter, transform, aggregate data ควรใช้ parallel stream เฉพาะเมื่อ dataset ใหญ่มากครับ