Comment puis-je ignorer l'appel de limite (nombre) avec un flux lorsque le nombre est égal à 0?

19

J'ai du code Java qui fournit des objets items. Il les limite en fonction maxNumber:

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

Cela fonctionne correctement, mais la question est la suivante: existe-t-il un moyen de sauter la limite lorsque le maxNumber == 0?

Je sais que je pourrais faire ça:

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

Mais peut-être y a-t-il une meilleure façon, est-ce que quelque chose vous vient à l'esprit?

randomuser1
la source

Réponses:

15

je suppose que

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

fera l'affaire, car il est très peu probable que vous allez attaquer un flux avec plus de 2 ^ 63-1 éléments ...

Au moins, soyez prudent avec les flux parallèles à ce sujet ... Une note dans les documents API dit:

Note de l'API : Bien qu'il s'agisselimit() généralement d'une opération bon marché sur les pipelines de flux séquentiel, elle peut être assez coûteuse sur les pipelines parallèles ordonnés, en particulier pour les grandes valeurs de maxSize ...

Jean-Baptiste Yunès
la source
oui, ça a fait l'affaire, merci!
randomuser1
20

Non, le pipeline de flux ne permet pas de fait sauter d' une partie de la canalisation, de sorte que vous êtes obligé de travailler soit avec une logique conditionnelle à l' intérieur des étapes et y compris le limit()toujours dans le pipeline ou la construction du flux dans les parties qui seraient un peu plus lisible (à mon humble avis) que si / sinon dans la question

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

Dans un cas simple comme ici, cela ne fait pas beaucoup de différence, mais vous voyez souvent dans les collections de code normales passer par des méthodes, être converties en flux, puis revenir aux collections. Dans de tels cas, il peut être préférable de travailler avec des flux en plusieurs parties jusqu'à ce que vous en ayez vraiment besoin collect().

Kayaman
la source