2016-10-07 24 views
10

Czy istnieje bardziej elegancki sposób osiągnięcia tego w Java 8?Java 8 collect() only isPresent() Opcjonalne wartości

list.stream() 
    .map(e -> myclass.returnsOptional(e)) 
    .filter(Optional::isPresent) 
    .map(Optional::get) 
    .collect(Collectors.toList()); 

mówię filter(Optional::isPresent) następnie map(Optional::get), chcę elegancko zbierać na liście tylko Optional wyników, które mają wartość.

+7

To wygląda dobrze do mnie. Nie jestem pewien, co ci się nie podoba. – khelwood

+0

Jeśli wszystkie opcje mają wynik, to nie jest już opcją ... zamiast zwracać opcjonalne i sprawdzać, czy isPresent można zwrócić wartości null i filtr, będzie o jeden krok krótszy. 'list.stream(). map (e -> myclass.returnsObjectOrNull (e)). filter (Objects :: non null) .collect (Collectors.toList())' – alfasin

+2

.map (o -> o.map (Stream: : of) .orElseGet (Stream :: empty)) lub zobacz odpowiedzi tutaj: http://stackoverflow.com/questions/22725537/using-java-8s-optional-with-streamflatmap – hasan

Odpowiedz

-1

Nie jestem pewien, czy jest tak różny, ale można go filtrować w oparciu o opcjonalne, zamiast opcjonalnego filtrowania. Coś takiego?

list.stream() 
    .filter(e -> myclass.returnsOptional(e).isPresent()) 
    .collect(Collectors.toList()); 

Uwaga: To będzie działać tylko wtedy, gdy returnsOptional zwraca ten sam typ obiektu jako oryginalnych typów elementów listy.

+0

Nie będzie to taka sama lista, jak ta, którą produkuje OP. – khelwood

+0

hmm, dlaczego by nie? –

+0

Ponieważ 'list' jest typu, powiedz' Foo' i 'myclass.returnsOptional (Foo)' zwraca 'Opcjonalnie '. W końcu potrzebuję 'List ' i produkujesz 'List ' –

1

W twoim przypadku możesz użyć jednego flatMap zamiast kombinacji mapfilter i ponownie map. Aby to zrobić, lepiej jest zdefiniować oddzielną funkcję tworzenia strumienia: public private static Stream<Integer> createStream(String e), aby nie mieć kilku linii kodu w wyrażeniu lambda.

proszę zobaczyć moje pełne przykład Demo:

public class Demo{ 
    public static void main(String[] args) { 
     List<String> list = Arrays.asList("1", "2", "Hi Stack!", "not", "5"); 
     List<Integer> newList = list.stream() 
       .flatMap(Demo::createStream) 
       .collect(Collectors.toList()); 
     System.out.println(newList); 
    } 

    public static Stream<Integer> createStream(String e) { 
     Optional<Integer> opt = MyClass.returnsOptional(e); 
     return opt.isPresent() ? Stream.of(opt.get()) : Stream.empty(); 
    } 
} 


class MyClass { 
    public static Optional<Integer> returnsOptional(String e) { 
     try { 
      return Optional.of(Integer.valueOf(e)); 
     } catch (NumberFormatException ex) { 
      return Optional.empty(); 
     } 
    } 
} 

w przypadku returnsOptional nie mogą być statyczne trzeba będzie użyć „strzałka” wyraz zamiast „metodą odniesienia”