Як я можу пропустити обмеження (номер) дзвінка потоком, коли число дорівнює 0?


19

У мене є деякий код Java, який забезпечує об’єкти з items. Він обмежує їх на основі maxNumber:

items.stream()
     .map(this::myMapper)
     .filter(item -> item != null)
     .limit(maxNumber)
     .collect(Collectors.toList());

Вона працює належним чином, але питання в цьому: Чи є спосіб пропустити обмеження, коли maxNumber == 0?

Я знаю, що міг би це зробити:

if (maxNumber == 0) {
    items.stream()
         .map(this::myMapper)
         .filter(item -> item != null)
         .collect(Collectors.toList());
} else {
    items.stream()
         .map(this::myMapper)
         .filter(item -> item != null)
         .limit(maxNumber)
         .collect(Collectors.toList());
}

Але, можливо, є кращий спосіб, чи щось вам спадає на думку?

Відповіді:


15

Я гадаю, що

.limit(maxNumber == 0 ? Long.MAX_VALUE : maxNumber)

це зробить трюк, оскільки це дуже неправдоподібно, що ви збираєтеся вирішити потік з більш ніж 2 ^ 63-1 елементами ...

Принаймні будьте обережні з паралельними потоками щодо цього ... Примітка в документах API говорить:

Примітка API : Хоча limit()це як правило дешева операція на послідовних потокових трубопроводах, вона може бути досить дорогою на упорядкованих паралельних трубопроводах, особливо для великих значень maxSize ...


так, це зробило трюк, дякую!
— randomuser1

20

Ні, трубопровід потоку не дозволяє насправді пропускати навколо будь-якої частини трубопроводу, тому ви змушені працювати з умовною логікою всередині етапів, включаючи limit()завжди в трубопроводі, або будувати потік у частинах, які були б трохи розбірливіше (ІМХО), ніж питання, якщо / ще у питанні

Stream<Item> s = items.stream()
         .map(this::myMapper)
         .filter(Objects::nonNull);

if(maxNumber > 0) {
    s = s.limit(maxNumber);
}

List<Item> l = s.collect(Collectors.toList());

У такому простому випадку, як тут, це не має великої різниці, але ви часто бачите в звичайних колекціях кодів, що передаються методами, перетворюються в потоки і потім повертаються до колекцій. У таких випадках може бути кращою ідеєю працювати з потоками в частинах, поки вам це не потрібно collect().

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.