2014-10-05 11 views
5

Qual è il meccanismo più idiomatico per applicare un lambda a ogni elemento di un elenco, restituendo un elenco composto dai risultati?Java 8 modo idiomatico per applicare una Lambda a una lista che restituisce un'altra lista?

Ad esempio:

List<Integer> listA = ... imagine some initialization code here ... 

List<Integer> listB = listA.apply(a -> a * a); // pseudo-code (there is no "apply") 

/* listB now contains the square of every value in listA */ 

Ho controllato le javadocs API e anche guardato in Apache Commons, ma non ho trovato nulla.

risposta

10

Per aggiungere a @ risposta di Eran Ho un metodo di supporto:

public static <T, R> List<R> apply(Collection<T> coll, Function<? super T, ? extends R> mapper) { 
    return coll.stream().map(mapper).collect(Collectors.toList()); 
} 

possono essere utilizzati come:

List<Integer> listB = apply(listA, a -> a * a); 

(Nota:. Richiede Java 1.8 o superiore)

+2

Questo si adatterebbe bene come metodo predefinito per le raccolte. –

+0

Questo è terribilmente inefficiente se si desidera applicare più di una singola operazione di mappatura. – AjahnCharles

+0

@CodeConfident puoi usare 'andThen' per combinare più funzioni prima di passarle a questo metodo. –

21

è possibile utilizzare un Stream con map e collect:

listB = listA.stream() 
      .map (a -> a*a) 
      .collect (Collectors.toList()); 
3

Il modo più standard è ad appena collect them alla fine:

List<Integer> listA = ... imagine some initialization code here ... 
List<String> listB = listA.stream() 
         .map(a -> a.toString()) 
         .collect(Collectors.toList()); 

Nota come la funzione mappa introduce una trasformazione da, in questo caso, Integer to a String, e l'elenco restituito è del tipo List<String>. La trasformazione viene eseguita dalla mappa e l'elenco viene generato dal raccoglitore.

1

Se non ti dispiace usare una libreria di terze parti, puoi usare potenti nuove collezioni.

// import javaslang.collection.*; 
listB = listA.map(f); 

Questi Java 8 collezioni sono immutabili e possono essere paragonate a quelle di Scala e Clojure. Si prega di leggere più here.

Btw - c'è anche zucchero sintattico per for-loop:

// import static javaslang.API.*; 
// import javaslang.collection.Stream; 
Stream<R> result = For(iterable1, ..., iterableN).yield((e1, ..., eN) -> ...); 

Disclaimer: io sono il creatore di Javaslang.

Problemi correlati