¿Cómo puedo omitir la llamada de límite (número) con una transmisión cuando el número es igual a 0?

19

Tengo un código Java que proporciona objetos de items. Los limita en función de maxNumber:

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

Funciona correctamente, pero la pregunta es la siguiente: ¿hay alguna forma de omitir la limitación cuando el maxNumber == 0?

Sé que podría hacer esto:

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

Pero tal vez hay una mejor manera, ¿se te ocurre algo?

randomuser1
fuente

Respuestas:

15

Supongo que

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

hará el truco, ya que es muy poco probable que abordes una secuencia con más de 2 ^ 63-1 elementos ...

Al menos tenga cuidado con las secuencias paralelas en esto ... Una nota en los documentos de la API dice:

Nota de API : Si bien limit()generalmente es una operación barata en tuberías de flujo secuencial, puede ser bastante costosa en tuberías paralelas ordenadas, especialmente para valores grandes de maxSize ...

Jean-Baptiste Yunès
fuente
sí, eso funcionó, gracias!
randomuser1
20

No, la canalización de flujo no permite omitir realmente ninguna parte de la tubería, por lo que se ve obligado a trabajar con la lógica condicional dentro de los pasos e incluir limit()siempre en la tubería, o construir la secuencia en partes que serían un poco más legible (en mi humilde opinión) que el if / else en la pregunta

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

En un caso simple como aquí, no hace mucha diferencia, pero a menudo se ve que las colecciones de códigos regulares se pasan a través de métodos, se convierten en secuencias y luego se vuelven a las colecciones. En tales casos, podría ser una mejor idea trabajar con secuencias en partes hasta que realmente lo necesite collect().

Kayaman
fuente