Recuperar una lista de java.util.stream.Stream en Java 8

Resuelto Daniel K. asked hace 11 años • 15 respuestas

Estaba jugando con lambdas de Java 8 para filtrar colecciones fácilmente. Pero no encontré una manera concisa de recuperar el resultado como una nueva lista dentro de la misma declaración. Aquí está mi enfoque más conciso hasta ahora:

List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList = new ArrayList<>();
sourceLongList.stream().filter(l -> l > 100).forEach(targetLongList::add);

Los ejemplos en la red no respondieron a mi pregunta porque se detienen sin generar una nueva lista de resultados. Debe haber una manera más concisa. Habría esperado que la Streamclase tuviera métodos como toList(),toSet()

¿Hay alguna manera de que las variables targetLongListpuedan asignarse directamente mediante la tercera línea?

Daniel K. avatar Feb 12 '13 17:02 Daniel K.
Aceptado

Lo que está haciendo puede ser la forma más sencilla, siempre que su transmisión permanezca secuencial; de lo contrario, tendrá que realizar una llamada a secuencial() antes forEach.

La razón por la que la llamada a secuencial() es necesaria es que el código tal como está ( forEach(targetLongList::add)) sería picante si la secuencia fuera paralela. Incluso entonces, no logrará el efecto deseado, ya que forEaches explícitamente no determinista: incluso en un flujo secuencial, el orden de procesamiento de los elementos no está garantizado. Tendría que utilizar forEachOrderedpara garantizar el pedido correcto. La intención de los diseñadores de Stream API es que usted utilice el recopilador en esta situación, como se muestra a continuación:

targetLongList = sourceLongList.stream()
    .filter(l -> l > 100)
    .collect(Collectors.toList());
Maurice Naftalin avatar Feb 12 '2013 12:02 Maurice Naftalin

Actualizado:

Otro enfoque es utilizar Collectors.toList:

targetLongList = 
    sourceLongList.stream().
    filter(l -> l > 100).
    collect(Collectors.toList());

Solución anterior:

Otro enfoque es utilizar Collectors.toCollection:

targetLongList = 
    sourceLongList.stream().
    filter(l -> l > 100).
    collect(Collectors.toCollection(ArrayList::new));
MohamedSanaulla avatar Mar 17 '2013 06:03 MohamedSanaulla

Hay un nuevo método Stream.toList() en Java 16, que acumula los elementos de la secuencia en una lista no modificable:

List<Long> targetLongList = sourceLongList
         .stream()
         .filter(l -> l > 100)
         .toList();
ZhekaKozlov avatar Jan 04 '2021 08:01 ZhekaKozlov