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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.