Как я могу пропустить вызов лимита (номера) с потоком, когда число равно 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());
}

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

randomuser1
источник

Ответы:

15

Я полагаю, что

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

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

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

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

Жан-Батист Юнес
источник
да, это помогло, спасибо!
randomuser1
20

Нет, потоковый конвейер не позволяет фактически пропускать какую-либо часть конвейера, поэтому вы вынуждены работать либо с условной логикой внутри шагов, включая limit()всегда в конвейере, либо строить поток по частям, которые будут чуть более разборчиво (ИМХО), чем в вопросе 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().

Kayaman
источник