سه راه برای ایجاد collector خود وجود دارد.
ما اولین را در این آموزش بررسی کردیم. شامل ترکیب collector های موجود با مکانیزمهای مختلف ارائهشده توسط کلاس factory Collectors، یعنی ارسال collector به عنوان downstream collector به collector دیگر یا استفاده از finisher با collector collectingAndThen() است.
همچنین میتوانید متد collect() را فراخوانی کنید که سه عنصری که collector بر اساس آن ساخته شده را میگیرد. این متدها هم در استریمهای انواع اولیه و هم در استریمهای اشیاء موجود هستند.
سومین راه شامل پیادهسازی مستقیم رابط Collector است. پیادهسازی collector خود به شما حداکثر انعطافپذیری میدهد اما فنیتر نیز هست.
بیایید پارامترهای این رابط را بررسی کنیم.
بیایید ابتدا انواع زیر را بررسی کنیم: T و R.
نوع اول T است و معادل نوع عناصر استریمی است که این collector پردازش میکند.
نوع آخر R است و نوعی است که توسط این collector تولید میشود.
برای collector toList() که روی نمونهای از Stream فراخوانی میشود، نوع R برابر List<T> خواهد بود. برای collector toSet() برابر Set<T> خواهد بود.
متد groupingBy() تابعی برای محاسبهی کلیدهای نقشهی برگرداندهشده میگیرد. اگر در حال جمعآوری Stream با این collector هستید، باید تابعی بدهید که بتواند نمونههای T را نگاشت کند. نوع نقشهی نتیجه Map<K, List<T>> خواهد بود.
نوع A پیچیدهتر است. اگر سعی کردهاید با IDE collector هایی که ساختید ذخیره کنید، احتمالاً متوجه شدهاید IDE مقدار صریحی برای این نوع نمیدهد.
اجرای کد قبلی خروجی زیر را چاپ میکند.
Size of list = 11
Size of set = 11
Size of map = 4
برای تمام این collector ها، نوع پارامتر دوم فقط ? است.
اگر نیاز به پیادهسازی رابط Collector دارید، باید مقدار صریحی به A بدهید. نوع A نوع container موقت قابل تغییری است که این collector استفاده میکند. برای collector toList() برابر ArrayList است و برای collector toSet() برابر HashSet.
یک collector ویژگیهای داخلی تعریف میکند که توسط پیادهسازی استریم برای بهینهسازی استفاده از این collector استفاده میشوند.
سه ویژگی وجود دارد:
IDENTITY_FINISH: نشان میدهد finisher این collector تابع همانی است. پیادهسازی برای collector با این ویژگی finisher را فراخوانی نمیکند.UNORDERED: نشان میدهد این collector ترتیب پردازش عناصر را حفظ نمیکند. این مورد collector toSet() است. اما collector toList() این ویژگی را ندارد.CONCURRENT: نشان میدهد container که accumulator عناصر پردازششده را در آن ذخیره میکند از دسترسی همزمان پشتیبانی میکند. این نکته برای استریمهای موازی مهم است.با این عناصر، اکنون میتوانید پیادهسازی collector ای که مانند toList() کار میکند بازسازی کنید.
این کد خروجی زیر را چاپ میکند.
result = [one, two, three, four, five]
پیادهسازی collector ای که مانند toSet() کار میکند فقط دو تغییر نیاز دارد:
supplier() HashSet::new برمیگرداند.characteristics() Characteristics.UNORDERED به مجموعهی برگرداندهشده اضافه میکند.بازسازی پیادهسازی این collector جالب است چون فقط روی رشتهها عمل میکند و finisher آن تابع همانی نیست.
این collector رشتههایی را که پردازش میکند در نمونهای از StringBuffer انباشته و سپس متد toString() را روی این accumulator فراخوانی میکند تا نتیجهی نهایی تولید شود.
مجموعهی ویژگیها برای این collector خالی است: ترتیب حفظ میشود (پس ویژگی UNORDERED ندارد)، finisher تابع همانی نیست، و نمیتواند همزمان استفاده شود.
اجرای این کد نتیجه زیر را تولید میکند.
result = onetwothreefourfive
پشتیبانی از جداکننده، پیشوند و پسوند از StringJoiner به جای StringBuilder استفاده میکند که از این عناصر پشتیبانی میکند.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://dev.java/learn/