sorted و distinct و limit و skip
sorted و distinct و limit و skip
رأيت سابقًا العمليات الوسيطة عديمة الحالة — filter وmap تعالج كل عنصر باستقلالية تامة دون الاطلاع على العناصر الأخرى. يركّز هذا الدرس على العمليات الوسيطة الأربع ذات الحالة ويُعرّفك بمفهوم الدوائر القصيرة (short-circuiting)، وكلاهما مهم للأداء والصحة.
عمليات ذات حالة مقابل عمليات عديمة الحالة
العملية عديمة الحالة لا تحتاج سوى العنصر الحالي. أما العملية ذات الحالة فتضطر إلى تجميع عدة عناصر أو فحصها قبل أن تُنتج أي مخرج. تمنحك واجهة Streams API أربع عمليات وسيطة ذات حالة:
sorted()— ترتيب جميع العناصرdistinct()— إزالة المكرراتlimit(n)— الاحتفاظ بأول n عناصر فقطskip(n)— تجاهل أول n عناصر
limit وskip في أبكر وقت ممكن حتى يصل عدد أقل من العناصر إلى العمليات الثقيلة لاحقًا.
sorted
sorted() بدون معاملات يرتّب بالترتيب الطبيعي (يجب أن تُنفّذ العناصر Comparable). مرّر Comparator للترتيب بأي مفتاح:
limit قبل sorted.
distinct
distinct() يُزيل العناصر المكررة باستخدام equals وhashCode، وهو يحافظ على الترتيب في streams التسلسلية (يفوز أول ظهور):
يكون ذلك مفيدًا بشكل خاص عند تسطيح مجموعات تظهر فيها القيمة ذاتها في قوائم فرعية متعددة.
equals وhashCode، وإلا سيمرّ كائنان متطابقان منطقيًا كلاهما.
limit و skip — عمليات الدائرة القصيرة
limit(n) يحتفظ بأول n عناصر على الأكثر ثم يوقف المسار. skip(n) يتجاهل أول n عناصر ويمرّر الباقي. معًا يُمكّنان من ترقيم صفحات stream:
مصطلح الدائرة القصيرة يعني أن المسار لا يحتاج إلى معالجة كل عناصر المصدر. حالما يُصدر limit حصته يُشير للمصدر بالتوقف. هذا نفس مفهوم && الذي يتوقف مبكرًا في التعبيرات المنطقية:
findFirst() وfindAny() وanyMatch() وnoneMatch() وallMatch() جميعها تستطيع إيقاف المسار مبكرًا. ستراها في درس لاحق عن Optional مع Streams.
الجمع بين العمليات الأربع في مسار حقيقي
سيناريو واقعي: من قائمة سطور سجل (logs)، ابحث عن أفضل 5 رسائل خطأ فريدة مرتبة أبجديًا، مع تخطي الأولى (لغرض الترقيم):
نصائح للأداء
- ضع
filterقبلsortedوdistinctلتقليل عدد العناصر التي تحتاج العمليات ذات الحالة إلى تخزينها. - ضع
limitفي أبكر وقت يسمح به المنطق — كل عنصر يُقطع قبل عملية ثقيلة يوفّر عملًا. - تجنّب
sortedعلى streams متوازية كبيرة ما لم يكن ضروريًا حقًا؛ إذ يُدخل خطوة دمج قد تُلغي فائدة التوازي.
الخلاصة
sorted وdistinct ذاتا حالة — يجب أن يريا جميع العناصر (أو كثيرًا منها) قبل إنتاج المخرج. limit وskip ذواتا دائرة قصيرة — تتوقف أو تتخطى مبكرًا مما يجعل streams اللانهائية عملية. وضع العمليات الثقيلة ذات الحالة في النهاية والعمليات ذات الدائرة القصيرة في البداية قاعدة بسيطة تُبقي المسارات فعّالة.