2017-05-02 27 views
5

Optional'un akıcı api'sini kullanmak ve buna iki Consumer s uygulamak istiyorum. Geçici değişkende saklamak zorunda kalmadan,İsteğe bağlı olarak nasıl göz atılır?

Optional.ofNullable(key) 
    .map(Person::get) 
    .ifPresent(this::printName) 
    .ifPresent(this::printAddress); // not compiling, because ifPresent is void 

Nasıl bir Optional için Consumer ler birkaç uygularım:

böyle bir şey hakkında hayal ediyorum? Alternatif

ofNullable(key) 
    .map(Person::get) 
    .ifPresent(x -> {printName(x); printAddress(x);}); 

: Sadece tek lambda içine her iki etkiyi birleştiren ediyorum, çok eleman görünmeyebilir bu iken

ofNullable(key) 
    .map(Person::get) 
    .map(x -> {printName(x);return x;}) 
    .map(x -> {printAddress(x);return x;}); 

cevap

4

Bu sözdizimini kullanabilirsiniz Ayrıca çok şık olmayan Consumer yöntem referansını kullanması gerekmesine rağmen, birden fazla Tüketiciyi zincirlemek için andThen'u da kullanabilirsiniz. Böyle

ofNullable(key) 
    .map(Person::get) 
    .ifPresent(((Consumer) this::printName).andThen(this::printAddress)); 
+3

, ben yan etkiler için 'map' kullanarak sanmıyorum iyi tarzıdır. Kişisel olarak, ifPresent (x -> {doA (x); doB (x);}) 'i kullanmayı tercih ederim. –

+2

@RobinTopper Bazen bunu yaparlar, çünkü kendi sorularına bir cevap bulmaya çalışmışlardır. birini bulmayı başaramadılar ve bir kez bulduklarında, bir sonraki araştırmacının cevabı bulduğundan emin olmak istiyorlar. – Esko

+0

Buradaki neden, Opsiyonel aslında tembel olarak değerlendirilen bir monad (Java_'de _yes) ve sadece son değerin iç boru hattının işlenmesinden sonra - başlangıçta bir değer yoksa, varsayılan davranışın başlatılmasıdır. Son değeri elde etmek için hangi yönteme bağlı olarak değişir. – Esko

6

ve ifPresent o geçmesi:

+0

Ben sizin benimkinden biraz daha iyi bir şekilde yaklaştığınızı seviyorum, çünkü onu daha açık hale getiriyor * açık */okunabilir olan şey aslında (iki eylem, diğerinden sonra yürütülür). – slartidan

1

Belki bir şey:

Optional.ofNullable(key) 
     .map(Person::get) 
     .ifPresent(combine(this::printAddress, this::printWish)); 

combine şudur: Bu işe yararken

public <T> Consumer<T> combine(Consumer<T>... cs) { 
    return x -> Stream.of(cs).peek(c -> c.accept(x)).close(); 
} 
+0

(Bu :: printName) .andThen (this :: printAddress) '(' ((Tüketici) ')' ye oldukça benzer, fakat ben onun varargs yönünü beğenirim (herhangi bir sayıda tüketiciye izin verir). – slartidan

+1

Ayrıca, tüketicileri bir dış kaynaktan param olarak alabilir ve eğer '' ve '' seçeneğini kullanırsanız, tüketicilerinizi gevşetmeli ve 've '' zinciri el ile oluşturmalısınız. –

İlgili konular