Spliterator: التقسيم لتحقيق التوازي
نفّذ Spliterator مخصصًا لعرض بيانات المجال كمصدر تدفق قابل للتقسيم
Spliterator: التقسيم لتحقيق التوازي درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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
Iterator: تسلسلي فقط، ولا يوفر تلميحًا عن الحجم ولا يدعم التقسيم. Spliterator: قادر على التوازي، ويوفر الخصائص وتقدير الحجم، ومصمم لواجهة Stream API.
تحقق سريع
ماذا يعيد trySplit() عندما لا يكون التقسيم ممكنًا؟
مراجعة
يُعد Spliterator محرك التدفقات المتوازية. طبّقوا tryAdvance وtrySplit وestimateSize وcharacteristics لعرض بنى البيانات المخصصة كتدفقات. استخدموا StreamSupport.stream(sp, true) لتفعيل التوازي.
الأسئلة الشائعة
هل درس «Spliterator: التقسيم لتحقيق التوازي» مجاني؟
نعم — نص درس «Spliterator: التقسيم لتحقيق التوازي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «Spliterator: التقسيم لتحقيق التوازي»؟
نفّذ Spliterator مخصصًا لعرض بيانات المجال كمصدر تدفق قابل للتقسيم تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «Spliterator: التقسيم لتحقيق التوازي»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- flatMap للمجموعات المتداخلة
- التدفقات المتوازية: الأداء والمشكلات
- Spliterator: التقسيم لتحقيق التوازي
- التدفقات اللانهائية باستخدام iterate وgenerate