Як я можу пропустити обмеження (номер) дзвінка потоком, коли число дорівнює 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.