2016-08-18 13 views
10

Załóżmy, że mamy listę w następujący sposób. CoreResult ma pole typu List<Double>.3 sposoby spłaszczania listy list. Czy istnieje powód, aby preferować jedno z nich?

final List<CoreResult> list = new LinkedList<>(SOME_DATA); 

Celem jest spłaszczyć listę po ekstrakcji tego konkretnego pola z każdego obiektu CoreResult. Oto 3 możliwe opcje. Czy któryś z nich jest lepszy od innych?

Wariant 1 wyodrębniania pola poprzez map() i spłaszczenie w środku kolektora

final List<Double> A = list.stream().map(CoreResult::getField) 
      .collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll); 

Wariant 2 wyodrębniania pola poprzez map(), spłaszczyć poprzez flatMap(), prosty kolektor

final List<Double> B = list.stream().map(CoreResult::getField) 
      .flatMap(Collection::stream).collect(Collectors.toList()); 

Opcja 3: wyodrębnić pole i spłaszczyć za jednym razem flatMap(), prosty kolektor

final List<Double> C = list.stream().flatMap(
      x -> x.getField().stream()).collect(Collectors.toList()); 

czy odpowiedź byłaby inna, gdyby nie było potrzeby, aby wyodrębnić z CoreResult dowolnego pola, a zamiast tego ktoś chciał po prostu spłaszczyć List<List<Double>>?

+2

Jeśli zależy Ci na wydajności, nie powinieneś używać 'LinkedList'. A ponieważ 'SOME_DATA' musi już być kolekcją, nie ma sensu kopiowanie jej do innej' Listy'. Tak więc preferowaną metodą jest 'SOME_DATA.stream()./* niezależnie od trzech opcji, które lubisz */'... – Holger

Odpowiedz

16

nie jestem pewien co do wykonywania każdego z nich, ale ważnym aspektem wzorzec budowniczego wykorzystywany przez strumienie Java jest taki, że pozwala na czytelność czytelności. Osobiście uważam, że opcja 2 jest najbardziej czytelna. Wariant 3 również jest dobry. Chciałbym uniknąć opcji pierwszej, ponieważ jest to rodzaj "oszustwa" spłaszczenia kolekcji.

Umieść każdą metodę we własnym wierszu i sprawdź, która jest najbardziej intuicyjna w odczycie. Ja raczej lubię drugi:

final List<Double> B = list.stream() 
          .map(CoreResult::getField) 
          .flatMap(Collection::stream) 
          .collect(Collectors.toList()); 
0

Opcje 3 i 2 są takie same, zależą od Ciebie, jeśli chcesz najpierw mapować, a następnie płaską mapę lub po prostu mapę płaską.

Przy opcji 1 należy otworzyć kolejny strumień, aby wykonać dalsze operacje.

7

chciałbym przejść do opcji 2 lub 3. Jeśli chcesz spłaszczyć List<List<Double>>, by to zrobić:

List<Double> list = doubleList.stream() 
           .flatMap(List::stream) 
           .collect(Collectors.toList());