JShell เป็น tool ใน Java 9 รับ simple statements เช่น expressions, variables, methods, classes แล้วผลลัพธ์ทันที
Stream คือ sequence ของ values Intermediate stream operation คือ operation ที่รับ stream เข้าไป ตัวอย่าง apply กับ lambda expression แล้วผลลัพธ์เป็น stream อีกทีหนึ่ง
Intermediate Operations ยอดนิยม
- 1) sorted(): เก็บ elements ของ consumed stream แต่เรียงตาม natural order
- 2) distinct(): คืน stream ที่มี unique elements เท่านั้น รักษา relative order
- 3) filter(): กรอง stream elements ตาม logic
- 4) map(): apply lambda expression คำนวณผลใหม่จาก input elements คืน stream ของผลลัพธ์
ตัวอย่างใน JShell
jshell> List<Integer> numbers = List.of(3, 10, 23, 200, 77, 9, 32);
numbers ==> [3, 10, 23, 200, 77, 9, 32]
jshell> numbers.stream().sorted().forEach(elem -> System.out.println(elem));
3
9
10
23
32
77
200
jshell> List<Integer> numbers = List.of(3, 5, 54, 280, 5, 9, 40);
numbers ==> [3, 5, 54, 280, 5, 9, 40]
jshell> numbers.stream().distinct().forEach(elem -> System.out.println(elem));
3
5
54
280
9
40
jshell> numbers.stream().distinct().sorted().forEach(elem -> System.out.println(elem));
3
5
9
40
54
280
jshell> numbers.stream().distinct().map(num -> num * num).forEach(elem -> System.out.println(elem));
9
25
2916
78400
81
1600
Intermediate Operations ทั้งหมด
| Operation | Type | คำอธิบาย | Short-circuit |
|---|---|---|---|
| filter(Predicate) | Filtering | กรองตามเงื่อนไข | ไม่ |
| map(Function) | Mapping | แปลงแต่ละ element | ไม่ |
| flatMap(Function) | Mapping | แปลงเป็น stream แล้ว flatten | ไม่ |
| distinct() | Filtering | unique elements เท่านั้น | ไม่ |
| sorted() | Sorting | เรียง natural order | ไม่ |
| sorted(Comparator) | Sorting | เรียงตาม comparator | ไม่ |
| peek(Consumer) | Inspection | ดูแต่ละ element (debug) | ไม่ |
| limit(long) | Slicing | จำกัด n elements แรก | ใช่ |
| skip(long) | Slicing | ข้าม n elements แรก | ไม่ |
| takeWhile(Predicate) | Slicing | รับจนกว่า predicate false (Java 9+) | ใช่ |
| dropWhile(Predicate) | Slicing | ข้ามจนกว่า predicate false (Java 9+) | ไม่ |
Stream Pipeline Pattern
// Source -> Intermediate ops -> Terminal op
List.of(1,2,3,4,5)
.stream() // Source
.filter(n -> n % 2 == 0) // Intermediate
.map(n -> n * n) // Intermediate
.sorted() // Intermediate
.forEach(System.out::println); // Terminal
// Output: 4, 16
Lazy Evaluation
Intermediate operations เป็น lazy - ไม่ทำงานจนกว่าจะมี terminal operation เรียก
jshell> Stream.of(1,2,3).peek(n -> System.out.println("peek: " + n))
// ไม่พิมพ์อะไร - ไม่มี terminal op
jshell> Stream.of(1,2,3).peek(n -> System.out.println("peek: " + n)).count();
// peek: 1
// peek: 2
// peek: 3
// $ ==> 3
Short-circuit Operations
บาง intermediate operations เป็น short-circuit - หยุดเร็วเมื่อเงื่อนไขเป็นจริง
// limit - short-circuit
Stream.iterate(1, n -> n + 1).limit(5).forEach(System.out::println);
// 1, 2, 3, 4, 5 (ไม่รันต่อไป)
// takeWhile - short-circuit (Java 9+)
Stream.of(1,2,3,4,5).takeWhile(n -> n < 4).forEach(System.out::println);
// 1, 2, 3 (หยุดที่ 4)