¿Por qué debo usar “operaciones funcionales” en lugar de un bucle for?

38
for (Canvas canvas : list) {
}

NetBeans me sugiere usar "operaciones funcionales":

list.stream().forEach((canvas) -> {
});

Pero, ¿por qué se prefiere ? En todo caso, es más difícil de leer y entender. Está llamando a stream() , luego a forEach() usando una expresión lambda con el parámetro canvas . No veo cómo es eso mejor que el bucle for en el primer fragmento.

Obviamente estoy hablando solo de estética. Tal vez hay una ventaja técnica aquí que me estoy perdiendo. ¿Qué es? ¿Por qué debería usar el segundo método en su lugar?

    
pregunta Omega 13.09.2015 - 21:12

3 respuestas

44

Los flujos proporcionan una abstracción mucho mejor para la composición de las diferentes operaciones que desea realizar sobre las colecciones o flujos de datos que llegan. Especialmente cuando necesita mapear elementos, filtrarlos y convertirlos.

Tu ejemplo no es muy práctico. Considere el siguiente código del sitio de Oracle .

List<Transaction> groceryTransactions = new Arraylist<>();
for(Transaction t: transactions){
  if(t.getType() == Transaction.GROCERY){
    groceryTransactions.add(t);
  }
}
Collections.sort(groceryTransactions, new Comparator(){
  public int compare(Transaction t1, Transaction t2){
    return t2.getValue().compareTo(t1.getValue());
  }
});
List<Integer> transactionIds = new ArrayList<>();
for(Transaction t: groceryTransactions){
  transactionsIds.add(t.getId());
}

se puede escribir usando flujos:

List<Integer> transactionsIds = 
    transactions.stream()
                .filter(t -> t.getType() == Transaction.GROCERY)
                .sorted(comparing(Transaction::getValue).reversed())
                .map(Transaction::getId)
                .collect(toList());

La segunda opción es mucho más legible. Por lo tanto, cuando tiene bucles anidados o varios bucles que realizan un procesamiento parcial, es un muy buen candidato para el uso de Streams / Lambda API.

    
respondido por el luboskrnac 13.09.2015 - 21:24
16

Otra ventaja de usar la API de transmisión funcional es que oculta los detalles de la implementación. Solo describe lo que debe hacerse, no cómo. Esta ventaja se hace evidente al observar el cambio que se debe hacer, para cambiar de ejecución de código de un solo hilo a paralelo. Solo cambia el .stream() a .parallelStream() .

    
respondido por el Stefan Dollase 14.09.2015 - 00:11
13
  

En todo caso, es más difícil de leer y entender.

Eso es altamente subjetivo. Encuentro la segunda versión mucho más fácil de leer y entender. Coincide con la forma en que lo hacen otros idiomas (p. Ej., Ruby, Smalltalk, Clojure, Io, Ioke, Seph), requiere menos conceptos para comprender (es solo una llamada de método normal como cualquier otra, mientras que el primer ejemplo es la sintaxis especializada). p>

En todo caso, es una cuestión de familiaridad.

    
respondido por el Jörg W Mittag 14.09.2015 - 05:17

Lea otras preguntas en las etiquetas