2014-10-05 7 views
5

Jaki jest najbardziej idiomatyczny mechanizm zastosowania lambda do każdej pozycji na liście, zwracając listę złożoną z wyników?Java 8 idiomatyczny sposób zastosowania Lambda do listy zwracającej inną listę?

Na przykład:

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 */ 

Sprawdziłem Javadocs API i również spojrzał w Apache Commons, ale nie znalazłem nic.

Odpowiedz

10

Aby dodać do @ odpowiedź Eran za Mam metodę pomocnika:

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

może być używany jako:

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

(Uwaga:. Będzie wymagać Java 1.8 lub wyższy)

+2

To ładnie pasuje jako domyślna metoda dla kolekcji. –

+0

Jest to bardzo nieefektywne, jeśli chcesz zastosować więcej niż jedną operację mapowania. – AjahnCharles

+0

@CodeConfident można użyć 'and Then), aby połączyć wiele funkcji przed przekazaniem ich do tej metody. –

21

Można użyć Stream z map i collect:

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

Najbardziej standardowym sposobem jest po prostu collect them na koniec:

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

Zauważ, że funkcja map wprowadza transformacji z, w tym przypadku wartość Integer na ciąg, a zwrócona lista jest typu List<String>. Transformacja jest wykonywana przez mapę, a lista jest generowana przez kolektor.

1

Jeśli nie masz nic przeciwko używaniu biblioteki innej firmy, możesz użyć nowych potężnych kolekcji.

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

Te kolekcje Java 8 są niezmienne i można je porównać do Scali i Clojure. Przeczytaj więcej here.

Btw - istnieje również cukier syntaktyczny dla pętli: for-

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

Disclaimer: Jestem twórcą Javaslang.

Powiązane problemy