Как я могу пропустить вызов лимита (номера) с потоком, когда число равно 0? - PullRequest
19 голосов
/ 12 марта 2020

У меня есть некоторый код Java, который предоставляет объекты из items. Он ограничивает их на основе maxNumber:

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

. Он работает правильно, но вопрос в следующем: есть ли способ пропустить ограничение, когда maxNumber == 0?

I знаю, я мог бы сделать это:

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());
}

Но, возможно, есть лучший способ, что-нибудь приходит на ум?

Ответы [ 2 ]

20 голосов
/ 12 марта 2020

Нет, потоковый конвейер не позволяет на самом деле пропускать любую часть конвейера, поэтому вы вынуждены работать с любой условной логикой c внутри шагов, включая limit() всегда в конвейере, или построение потока частями, которые были бы немного более разборчивыми (IMHO), чем if / else в вопросе

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().

15 голосов
/ 12 марта 2020

Полагаю, что

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

справится с задачей, так как маловероятно, что вы собираетесь заняться потоком с более чем 2 ^ 63-1 элементами ...

По крайней мере, будьте осторожны с параллельными потоками в этом ... Примечание в документации API гласит:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...