คลาส Collectors เป็นส่วนสำคัญของ Stream API ใน Java 9 เพิ่มเมธอดใหม่: filtering() เข้าไปใน Collectors class เมธอด Collectors.filtering() ใช้กรอง elements ใน stream คล้ายกับเมธอด filter() บน streams ความแตกต่างคือ filter() ประมวลผล values ก่อนที่จะ group ในขณะที่ filtering() ใช้ร่วมกับ Collectors.groupingBy() ได้อย่างดี เพื่อ group values ก่อนที่ขั้นตอน filtering จะเกิดขึ้น
ไวยากรณ์
public static <T, A, R> Collector<T, ?, R> filtering(
Predicate<? super T> predicate,
Collector<? super T, A, R> downstream)
ตัวอย่างการใช้งาน
import java.util.stream.*;
import java.util.*;
public class FilteringMethodTest {
public static void main(String args[]) {
List<String> list = List.of("x", "yy", "zz", "www");
Map<Integer, List<String>> result = list.stream()
.collect(Collectors.groupingBy(
String::length,
Collectors.filtering(s -> !s.contains("z"), Collectors.toList())
));
System.out.println(result);
}
}
ผลลัพธ์
{1=[x], 2=[yy], 3=[www]}
คำอธิบายตัวอย่าง
- List: "x" (len 1), "yy" (len 2), "zz" (len 2), "www" (len 3)
- groupingBy String::length → 3 groups: 1, 2, 3
- filtering: ในแต่ละ group กรองเฉพาะ string ที่ไม่มี 'z'
- Group 1: ["x"] → ไม่มี 'z' → คงอยู่
- Group 2: ["yy", "zz"] → "yy" ไม่มี 'z' คงอยู่, "zz" มี 'z' ถูกกรองทิ้ง
- Group 3: ["www"] → ไม่มี 'z' → คงอยู่
- ผลลัพธ์: {1=[x], 2=[yy], 3=[www]}
ความแตกต่าง filter() vs filtering()
| เมธอด | ตำแหน่งใน pipeline | ใช้กับ |
|---|---|---|
| stream.filter() | ก่อน collect() | Stream<T> ทั่วไป |
| Collectors.filtering() | ใน collector (downstream) | groupingBy, partitioningBy |
ประโยชน์ของ filtering()
- กรองข้อมูล หลังจาก group แล้ว รักษาโครงสร้าง group ไว้
- กลุ่มที่ว่างเปล่าจะไม่ปรากฏในผลลัพธ์ (ไม่มี key สำหรับกลุ่มว่าง)
- รวมการ group และ filter ใน collector เดียว ได้โค้ดสะอาดกว่า
filtering() เหมาะสำหรับการจัดกลุ่มแล้วค่อยกรองข้อมูลภายในแต่ละกลุ่ม