Wie kann ich den Limit (Nummer) -Anruf mit einem Stream überspringen, wenn die Nummer gleich 0 ist?

19

Ich habe Java-Code, der Objekte von bereitstellt items. Es begrenzt sie basierend auf maxNumber:

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

Es funktioniert richtig, aber die Frage ist: Gibt es eine Möglichkeit, die Begrenzung zu überspringen, wenn die maxNumber == 0?

Ich weiß, dass ich das tun kann:

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

Aber vielleicht gibt es einen besseren Weg, fällt Ihnen etwas ein?

randomuser1
quelle

Antworten:

15

ich vermute das

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

wird den Trick machen, da es sehr unwahrscheinlich ist, dass Sie einen Stream mit mehr als 2 ^ 63-1 Elementen angehen ...

Seien Sie zumindest vorsichtig mit parallelen Streams ... Ein Hinweis in API-Dokumenten lautet:

API-Hinweis : Während dies limit()bei sequentiellen Stream-Pipelines im Allgemeinen ein billiger Vorgang ist, kann es bei bestellten parallelen Pipelines recht teuer sein, insbesondere bei großen Werten von maxSize ...

Jean-Baptiste Yunès
quelle
Ja, das hat den Trick gemacht, danke!
randomuser1
20

Nein, die Stream-Pipeline erlaubt es nicht, einen Teil der Pipeline tatsächlich zu überspringen, sodass Sie gezwungen sind, entweder mit bedingter Logik innerhalb der Schritte zu arbeiten und die limit()immer in der Pipeline zu enthalten, oder den Stream in Teilen zu erstellen, die dies wären etwas besser lesbar (IMHO) als das if / else in der Frage

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

In einem einfachen Fall wie hier macht es keinen großen Unterschied, aber Sie sehen oft, dass reguläre Codesammlungen Methoden durchlaufen, in Streams konvertiert und dann zurück in Sammlungen. In solchen Fällen ist es möglicherweise besser, mit Streams in Teilen zu arbeiten, bis dies wirklich erforderlich ist collect().

Kayaman
quelle