2016-10-07 48 views
10

Java 8'de bunu pratik olarak gerçekleştirmenin daha zarif bir yolu var mı? Ben yaklaşık filter(Optional::isPresent)map(Optional::get) ardından bahsediyorumJava 8 collect() only isPresent() Opsiyonel değerler

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

, ben zarif bir listede bir değere sahip tek Optional sonuçları toplamak istiyoruz.

+7

O bana iyi göründü ifadesini "ok" gerekecektir statik olamaz:

benim tam Demo örneğine bakın. Ne sevmediğinden emin değilim. – khelwood

+0

Tüm Optional'larınızın bir sonucu varsa, bu isteğe bağlı değildir. İsteğe bağlı olarak dönmek ve isPresent olup olmadığını kontrol etmek için boş değerlere ve filtrelere geri dönmek yerine bir adım daha kısa olacaktır. map.stream(). map (e -> myclass.returnsObjectOrNull (e)) filter (Nesneler :: nonNull) .collect (Collectors.toList()) ' – alfasin

+2

.map (o -> o.map (Akış: : of) .orElseGet (Stream :: empty)) veya burada cevapları bakın: http://stackoverflow.com/questions/22725537/using-java-8s-optional-with-streamflatmap – hasan

cevap

-1

Çok farklı olduğundan emin değilsiniz, ancak isteğe bağlı ve isteğe bağlı filtrelemeyi almak yerine isteğe bağlı olarak filtreleyebilirsiniz. Böyle bir şey mi var?

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

Not: returnsOptional orijinal liste öğesi türleri olarak aynı nesne türünü döndürür Bu sadece çalışacaktır.

+0

yerine .map (myclass :: returnsOptional) 'dır. Bu, OP'nin ürettiği ile aynı listeyi üretmeyecektir. – khelwood

+0

hmm neden olmasın? –

+0

'List' türünde 'Foo' ve' myclass.returnsOptional (Foo) 'türlerinden biri' 'İsteğe bağlı ' döndürür. Sonunda Listesine ihtiyacım var ve "" –

1

Sizin durumunuzda mapfilter ve map yeniden birleştirmeler yerine bir flatMap kullanabilirsiniz. Bunu yapmak için, Stream: public private static Stream<Integer> createStream(String e), lambda ifadesinde birçok kod satırının olmaması için ayrı bir işlev tanımlamak daha iyidir. dava returnsOptional içinde

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(); 
     } 
    } 
} 

Kullanmak yerine "yöntemi referansı"