Spliterator: การแบ่งเพื่อการทำงานแบบขนาน
สร้าง Spliterator แบบกำหนดเองเพื่อเปิดให้ข้อมูลเฉพาะโดเมนเป็นแหล่งสตรีมที่แบ่งได้
Spliterator: การแบ่งเพื่อการทำงานแบบขนาน เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
Spliterator คืออะไร
Spliterator (ตัววนซ้ำที่แบ่งได้) คือกลไกหลักเบื้องหลังสตรีม โดยจะวนซ้ำผ่านองค์ประกอบต่าง ๆ และสามารถแบ่งตัวเองออกเป็นสองส่วนเพื่อการประมวลผลแบบขนาน
เมธอดหลักของ Spliterator
เมธอดหลักสี่รายการ ได้แก่ tryAdvance (ประมวลผลหนึ่งองค์ประกอบ), forEachRemaining (ประมวลผลองค์ประกอบที่เหลือทั้งหมด), trySplit (แบ่งออกเป็นสองส่วน) และ estimateSize (ประมาณจำนวนองค์ประกอบ)
Spliterator<Integer> sp = List.of(1,2,3,4,5,6).spliterator();
Spliterator<Integer> half = sp.trySplit(); // splits off first ~half
half.forEachRemaining(System.out::println); // 1 2 3
sp.forEachRemaining(System.out::println); // 4 5 6คุณลักษณะของ Spliterator
Spliterator จะประกาศคุณลักษณะด้วยแฟล็กบิต ได้แก่ SIZED, ORDERED, DISTINCT, SORTED, NONNULL, IMMUTABLE, CONCURRENT และ SUBSIZED
Spliterator<String> sp = List.of("a","b","c").spliterator();
System.out.println(Integer.toBinaryString(sp.characteristics()));
// Characteristics include ORDERED, SIZED, SUBSIZEDการทำงานของ trySplit
trySplit() จะคืนค่า Spliterator ใหม่ที่ครอบคลุมองค์ประกอบที่เหลือประมาณครึ่งหนึ่ง ส่วนออบเจ็กต์เดิมจะครอบคลุมอีกครึ่งหนึ่ง ให้คืนค่า null หากไม่สามารถแบ่งได้
// ArrayList Spliterator splits efficiently at midpoint:
// [0,1,2,3,4,5] -> [0,1,2] (new) + [3,4,5] (original)การสร้าง Spliterator แบบกำหนดเอง
ใช้ Spliterator<T> เพื่อเปิดเผยโครงสร้างข้อมูลแบบกำหนดเองให้เป็นแหล่งข้อมูลของสตรีม กำหนด trySplit เพื่อเปิดใช้งานการประมวลผลแบบขนาน
public class RangeSpliterator implements Spliterator<Integer> {
private int start, end;
public RangeSpliterator(int start, int end) { this.start=start; this.end=end; }
public boolean tryAdvance(Consumer<? super Integer> action) {
if (start >= end) return false;
action.accept(start++); return true;
}
public Spliterator<Integer> trySplit() {
int mid = (start + end) / 2;
if (mid <= start) return null;
RangeSpliterator prefix = new RangeSpliterator(start, mid);
this.start = mid; return prefix;
}
public long estimateSize() { return end - start; }
public int characteristics() { return ORDERED | SIZED | SUBSIZED | IMMUTABLE; }
}การสร้างสตรีมจาก Spliterator
ใช้ StreamSupport.stream(spliterator, parallel) เพื่อสร้างสตรีมจาก Spliterator ใดก็ได้ ซึ่งเป็นสะพานเชื่อมระหว่างแหล่งข้อมูลแบบกำหนดเองกับ Stream API
Spliterator<Integer> sp = new RangeSpliterator(0, 1_000_000);
Stream<Integer> stream = StreamSupport.stream(sp, true); // true = parallel
long count = stream.filter(n -> n % 2 == 0).count();
System.out.println(count); // 500000Spliterator สำหรับต้นไม้ไบนารี
Spliterator แบบกำหนดเองช่วยให้โครงสร้างที่ไม่ใช่ลิสต์ เช่น ต้นไม้ รองรับการประมวลผลแบบขนานได้ trySplit จะคืนค่า Spliterator ของต้นไม้ย่อยด้านซ้ายและเก็บด้านขวาไว้
ประสิทธิภาพแบบขนานและคุณภาพการแบ่ง
สตรีมแบบขนานจะแบ่งข้อมูลซ้ำไปเรื่อย ๆ จนกว่าชิ้นข้อมูลจะเล็กพอสำหรับเธรดเดียว การแบ่งที่ดีต้องอาศัย estimateSize ที่แม่นยำและการแบ่งที่มีขนาดใกล้เคียงกัน
forEachRemaining สำหรับการประมวลผลเป็นกลุ่ม
หากไม่จำเป็นต้องแบ่งข้อมูล ให้เขียนทับ forEachRemaining เพื่อประมวลผลเป็นกลุ่ม ซึ่งช่วยหลีกเลี่ยงค่าใช้จ่ายต่อองค์ประกอบจากการเรียก tryAdvance ในลูป
@Override
public void forEachRemaining(Consumer<? super Integer> action) {
for (int i = start; i < end; i++) action.accept(i);
start = end; // mark as exhausted
}Spliterator เทียบกับตัววนซ้ำ
Iterator: ทำงานตามลำดับเท่านั้น ไม่มีคำใบ้ขนาด และแบ่งไม่ได้ Spliterator: รองรับการทำงานแบบขนาน ให้คุณลักษณะและค่าประมาณขนาด และออกแบบมาสำหรับ Stream API
ตรวจสอบความเข้าใจอย่างรวดเร็ว
trySplit() คืนค่าอะไรเมื่อไม่สามารถแบ่งได้
ทบทวน
Spliterator คือกลไกขับเคลื่อนสตรีมแบบขนาน ใช้ tryAdvance, trySplit, estimateSize และ characteristics เพื่อเปิดเผยโครงสร้างข้อมูลแบบกำหนดเองให้เป็นสตรีม ใช้ StreamSupport.stream(sp, true) เพื่อเปลี่ยนไปทำงานแบบขนาน
คำถามที่พบบ่อย
บทเรียน “Spliterator: การแบ่งเพื่อการทำงานแบบขนาน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “Spliterator: การแบ่งเพื่อการทำงานแบบขนาน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “Spliterator: การแบ่งเพื่อการทำงานแบบขนาน”
สร้าง Spliterator แบบกำหนดเองเพื่อเปิดให้ข้อมูลเฉพาะโดเมนเป็นแหล่งสตรีมที่แบ่งได้ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “Spliterator: การแบ่งเพื่อการทำงานแบบขนาน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- flatMap สำหรับคอลเลกชันแบบซ้อน
- สตรีมแบบขนาน: ประสิทธิภาพและข้อควรระวัง
- Spliterator: การแบ่งเพื่อการทำงานแบบขนาน
- สตรีมไม่สิ้นสุดด้วย iterate และ generate