جاوا استریمها در جاوا 8 در سال 2014 معرفی شدهاند تا جاوا را به یک الگوی برنامهنویسی کاربردی معرفی کنند. جاوا استریم ها بسیاری از عملیات عملکردی انعطاف پذیر و قدرتمند را برای انجام پردازش مجموعه در یک لاینر به نمایش می گذارد.
فیلتر کردن مجموعهها بر اساس برخی از گزارهها یکی از متداولترین عملیات کاربردی است و میتواند با Predicate
یا به طور خلاصه - با الف بیان لامبدا.
در این راهنمای کوتاه، به نحوه فیلتر کردن جریان جاوا 8 با عبارات لامبدا خواهیم پرداخت.
فیلتر کردن جریان ها در جاوا
به طور کلی، هر Stream
را می توان از طریق فیلتر کرد filter()
روش، و یک محمول داده شده:
Stream filter(Predicate<? super T> predicate)
هر عنصر در جریان بر خلاف گزاره اجرا می شود و در صورت بازگشت گزاره به جریان خروجی اضافه می شود. true
. شما می توانید یک Predicate
نمونه، مثال:
Predicate contains = s -> s.contains("_deprecated");
List results = stream.filter(contains).collect(Collectors.toList());
یا با ارائه یک عبارت Lambda آن را ساده کنید:
List results = stream.filter(s -> s.contains("_deprecated"))
.collect(Collectors.toList());
یا حتی عبارت لامبدا را به یک جمع کنید مرجع روش:
List results = stream.filter(String::isEmpty)
.collect(Collectors.toList());
با مراجع متد، نمیتوانید آرگومانها را ارسال کنید، هرچند، میتوانید متدهایی را در شیئی که فیلتر میکنید تعریف کنید و آنها را طوری تنظیم کنید که به راحتی قابل فیلتر باشند (تا زمانی که متد آرگومانها را قبول نکند و یک عدد را برگرداند. boolean
).
به یاد داشته باشید که جریان ها مجموعه نیستند - آنها جریان هستند از مجموعه ها، و شما باید آنها را در هر مجموعه ای مانند a جمع آوری کنید List
, Map
و غیره به آنها ماندگاری بدهد. علاوه بر این، تمام عملیات بر روی عناصر جریان نیز انجام می شود متوسط or پایانه:
- عملیات میانی یک جریان جدید را با تغییراتی نسبت به عملیات قبلی برمی گرداند
- عملیات ترمینال یک نوع داده را برمی گرداند و به منظور پایان دادن به خط لوله پردازش در یک جریان است
filter()
است متوسط عملیات، و قرار است قبل از پایان جریان، با سایر عملیات میانی زنجیر شود. برای تداوم هر گونه تغییر (مانند تغییرات در خود عناصر یا نتایج فیلتر شده)، باید نتیجه را اختصاص دهید جریان خروجی به یک متغیر مرجع جدید، از طریق عملیات ترمینال.
توجه داشته باشید: حتی زمانی که بسیاری از عبارات لامبدا را به صورت زنجیرهای در میآورید، ممکن است با شکستهای خطی مناسب، با مشکلات خوانایی مواجه نشوید.
در مثالهای زیر، با این فهرست کتابها کار خواهیم کرد:
Book book1 = new Book("001", "Our Mathematical Universe", "Max Tegmark", 432, 2014);
Book book2 = new Book("002", "Life 3.0", "Max Tegmark", 280, 2017);
Book book3 = new Book("003", "Sapiens", "Yuval Noah Harari", 443, 2011);
List books = Arrays.asList(book1, book2, book3);
مجموعه فیلتر با Stream.filter()
بیایید این مجموعه کتاب را فیلتر کنیم. هر گزارهای وجود دارد - بنابراین اجازه دهید برای مثال فیلتر کنیم که کتابها بیش از 400 صفحه دارند:
List results = books.stream()
.filter(b -> b.getPageNumber() > 400)
.collect(Collectors.toList());
این منجر به لیستی می شود که شامل:
[
Book{id='001', name='Our Mathematical Universe', author='Max Tegmark', pageNumber=432, publishedYear=2014},
Book{id='003', name='Sapiens', author='Yuval Noah Harari', pageNumber=443, publishedYear=2011}
]
هنگام فیلتر کردن، یک روش واقعاً مفید برای زنجیر کردن است map()
، که به شما امکان می دهد اشیاء را به مقدار دیگری نگاشت کنید. به عنوان مثال، ما می توانیم هر کتاب را به نام خود نگاشت کنیم، و بنابراین فقط آن را برگردانیم نام از کتاب های متناسب با محمول از filter()
زنگ زدن:
List results = books.stream()
.filter(b -> b.getPageNumber() > 400)
.map(Book::getName)
.collect(Collectors.toList());
این منجر به لیستی از رشته ها می شود:
[Our Mathematical Universe, Sapiens]
مجموعه فیلتر بر روی چند محمول با Stream.filter()
معمولاً، ما می خواهیم مجموعه ها را با بیش از یک معیار فیلتر کنیم. این را می توان با زنجیر کردن چندگانه انجام داد filter()
تماس or با استفاده از یک گزاره اتصال کوتاه، که دو شرط را در یک واحد بررسی می کند filter()
زنگ زدن.
List results = books.stream()
.filter(b -> b.getPageNumber() > 400 && b.getName().length() > 10)
.collect(Collectors.toList());
List results2 = books.stream()
.filter(b -> b.getPageNumber() > 400)
.filter(b -> b.getName().length() > 10)
.collect(Collectors.toList());
راهنمای عملی و عملی ما برای یادگیری Git را با بهترین روش ها، استانداردهای پذیرفته شده در صنعت و برگه تقلب شامل بررسی کنید. دستورات Google Git را متوقف کنید و در واقع یاد گرفتن آی تی!
هنگام استفاده از چندین معیار - تماس های لامبدا می تواند تا حدودی طولانی شود. در این مرحله، استخراج آنها به عنوان محمولات مستقل ممکن است وضوح بیشتری ارائه دهد. با این حال، کدام رویکرد سریعتر است؟
یک فیلتر با شرایط پیچیده یا چند فیلتر؟
این بستگی به سخت افزار شما دارد، مجموعه شما چقدر بزرگ است و اینکه آیا از جریان های موازی استفاده می کنید یا خیر. به طور کلی – یک فیلتر با شرایط پیچیده از چندین فیلتر با شرایط ساده تر (مجموعه های کوچک تا متوسط) بهتر عمل می کند یا در همان سطح (مجموعه های بسیار بزرگ) عمل می کند. اگر شرایط شما خیلی طولانی است - ممکن است از توزیع آنها در چند مورد سود ببرید filter()
نیاز به خوانایی بهتر دارد، زیرا عملکرد بسیار مشابه است.
بهترین انتخاب این است که هر دو را امتحان کنید، به عملکرد آن توجه کنید دستگاه مورد نظرو استراتژی خود را بر اساس آن تنظیم کنید.
کاربر GitHub ولکوداوها یک معیار فیلترینگ در عملیات/های توان عملیاتی انجام داد و نتایج را روی آن میزبانی کرد جاوا فیلترها-معیارها مخزن نتایج در یک جدول آموزنده خلاصه شده است:
این کاهش واضح بازده در اندازه های کلکسیون بزرگتر را نشان می دهد، با هر دو رویکرد در حدود یک سطح. جریان های موازی به طور قابل توجهی در اندازه های مجموعه بزرگتر سود می برند، اما عملکرد را در اندازه های کوچکتر محدود می کنند (عناصر کمتر از 10k). شایان ذکر است که جریانهای موازی توان عملیاتی خود را بسیار بهتر از جریانهای غیر موازی حفظ میکنند و به طور قابلتوجهی برای ورودی قویتر میشوند.