ทั้งคู่ใช้สำหรับ **iterate collections** แต่ Spliterator (Java 8+) ออกแบบมาสำหรับ **Parallel Processing** และ **Streams**
ตารางเปรียบเทียบ
| ลำดับ | หัวข้อ | Iterator | Spliterator |
|---|---|---|---|
| 1 | พื้นฐาน | Sequential traversal เท่านั้น | Sequential + **Parallel** traversal |
| 2 | Package | java.util.Iterator | java.util.Spliterator |
| 3 | Bulk Operations | ไม่รองรับ (ต้อง loop เอง) | รองรับ forEachRemaining(), trySplit() |
| 4 | Iteration Type | External Iterator (client ควบคุม loop) | Internal Iterator (Spliterator ควบคุม เอง) |
| 5 | Splitting | ไม่สามารถ split ได้ | trySplit() แยกเป็นส่วนๆ สำหรับ parallel |
| 6 | Size Estimation | ไม่มี | estimateSize(), getExactSizeIfKnown() |
| 7 | Characteristics | ไม่มี | มี characteristics (ORDERED, SORTED, DISTINCT, SIZED, ...) |
| 8 | Stream Integration | ไม่ใช่ (แต่ Collection.iterator() ใช้ได้) | **Core ของ Stream API** - collection.spliterator() |
Iterator - External Iteration
Listlist = Arrays.asList("A", "B", "C", "D"); // Client ควบคุมการ loop Iterator it = list.iterator(); while (it.hasNext()) { String element = it.next(); System.out.println(element); } // หรือ for-each (syntax sugar) for (String s : list) { System.out.println(s); }
Spliterator - Internal Iteration + Splitting
Methods หลัก
boolean tryAdvance(Consumer<T> action)- ประมวลผล 1 element (เหมือน hasNext+next)void forEachRemaining(Consumer<T> action)- ประมวลผลทุก element ที่เหลือSpliterator<T> trySplit()- **พยายามแยก** ส่วนหนึ่งออกไป (สำหรับ parallel)long estimateSize()- ประมาณจำนวน elementsint characteristics()- ลักษณะ (ORDERED, SORTED, DISTINCT, SIZED, SUBSIZED, NONNULL, IMMUTABLE, CONCURRENT)
ตัวอย่าง Spliterator พื้นฐาน
import java.util.*;
import java.util.Spliterator;
public class SpliteratorExample {
public static void main(String[] args) {
List list = Arrays.asList(78, 10, 20, 30, 40, 50, 60, 70);
Spliterator spliterator = list.spliterator();
System.out.println("Characteristics: " + spliterator.characteristics());
System.out.println("Estimated size: " + spliterator.estimateSize());
System.out.println("Exact size known: " + spliterator.getExactSizeIfKnown());
// Split ลองแยกครึ่ง
Spliterator split = spliterator.trySplit();
System.out.println("\nOriginal (remaining):");
spliterator.forEachRemaining(System.out::println);
System.out.println("\nSplit part:");
split.forEachRemaining(System.out::println);
}
}
Output
Characteristics: 16464 (ORDERED | SIZED | SUBSIZED | DISTINCT | IMMUTABLE) Estimated size: 8 Exact size known: 8 Original (remaining): 50 60 70 40 Split part: 10 20 30 78
Spliterator และ Parallel Streams
Stream ใช้ Spliterator ภายในเพื่อ parallel processing:
Listnumbers = IntStream.rangeClosed(1, 1_000_000).boxed().toList(); // Sequential - ใช้ 1 thread long sumSeq = numbers.stream().mapToLong(Long::valueOf).sum(); // Parallel - Spliterator แยกงานให้หลาย threads long sumPar = numbers.parallelStream().mapToLong(Long::valueOf).sum(); // Spliterator characteristics ช่วย optimize: // - SIZED: รู้ขนาดแน่นอน → divide ง่าย // - SUBSIZED: split parts ก็รู้ขนาด → divide ต่อได้ // - ORDERED: ต้องรักษาลำดับ → restrict parallelism บ้าง // - DISTINCT: ไม่มี duplicate → optimize distinct()
Custom Spliterator (Advanced)
// Spliterator สำหรับ generate Fibonacci numbers (Infinite) public class FibonacciSpliterator implements Spliterator{ private long prev = 0, next = 1; private long count = 0; private final long maxCount; public FibonacciSpliterator(long maxCount) { this.maxCount = maxCount; this.characteristics = Spliterator.ORDERED | Spliterator.NONNULL | Spliterator.IMMUTABLE; } @Override public boolean tryAdvance(Consumer super Long> action) { if (count >= maxCount) return false; action.accept(prev); long temp = prev + next; prev = next; next = temp; count++; return true; } @Override public Spliterator trySplit() { // Fibonacci ไม่สะดวก split (stateful) - return null return null; } @Override public long estimateSize() { return maxCount - count; } @Override public int characteristics() { return characteristics; } // ใช้กับ Stream Stream fibStream = StreamSupport.stream(new FibonacciSpliterator(100), false);
สรุป: เมื่อไหร่ใช้อะไร?
| สถานการณ์ | ใช้ | เหตุผล |
|---|---|---|
| Simple loop, for-each | Iterator / for-each | เข้าใจง่าย, พอเพียง |
| ต้อง remove() ระหว่าง loop | Iterator | มี remove() method |
| Parallel processing, Streams | Spliterator | Core ของ parallel streams |
| Custom data structure ต้องการ parallel | Custom Spliterator | Implement trySplit() ให้ถูกต้อง |
| Batch processing ทั้งชุด | Spliterator.forEachRemaining() | Internal iteration, optimized |