2016-04-03 20 views
12

Birçok lambda'lar formunu bu kadar sık ​​böyle bunun için bir yöntem yazdım bunuFonksiyonlar tüketicilerin internetten dönüştürme

t -> { 
    // do something to t 
    return t; 
} 

alır.

static <T> Function<T, T> consumeThenReturn(Consumer<T> consumer) { 
    return t -> { 
     consumer.accept(t); 
     return t; 
    }; 
} 

Bu beni böyle gerçekten güzel şeyler yapmak sağlar: Kendi yönteme dayanmadan böyle dönüşümleri yapmanın başka bir yolu

IntStream.rangeClosed('A', 'Z') 
     .mapToObj(a -> (char) a) 
     .collect(Collectors.collectingAndThen(Collectors.toList(), consumeThenReturn(Collections::shuffle))) 
     .forEach(System.out::print); 

var mı? Kaçırdığım yeni API'larda, yöntemimi gereksiz kılan bir şey var mı?

+4

Orada olduğunu sanmıyorum: örneğin Collectors.toList() koduna bakın, bunu yapar (sol, sağ) -> {left.addAll (right); sola dönün; } '. Bu onların argümanını mutasyona sokan metotların problemidir ... (yan not, '' Fonksiyon ' yerine ' 'UnaryOperator' ı kullanabilirsiniz – Tunaki

+3

Fonksiyonunuzu ['tee'] olarak yeniden adlandırabilirim (https: //en.wikipedia .org/wiki/Tee_ (komut)). – dasblinkenlight

+0

Her şey çoktan söylendi, ama zaten bunu yapan bir şey üzerinde çalışıyorum. https://github.com/TouK/ThrowingFunction/ herhangi bir giriş takdir edilir –

cevap

6

Function, Consumer ve Supplier arabirimlerine eklenebilecek birçok olası yararlı yöntem vardır. İyi bir örnek verirsiniz (Consumer'un bir Function'a dönüştürülmesi) ancak eklenebilecek başka birçok potansiyel dönüşüm veya yardımcı program vardır. Örneğin, bir Function kullanarak Consumer (dönüş değerini göz ardı ederek) veya Supplier (bir giriş değeri sağlayarak). Ya da BiFunction değerini Function'a herhangi bir değer vererek sağlarız. Bunların hepsi, elbette, el ile kodda yapılır veya gösterdiğiniz gibi yardımcı işlevler aracılığıyla yapılabilir, ancak diğer birçok dilde mevcut olduğu gibi API'da standartlaştırılmış mekanizmaların olması değerli olabilir.

Bu bölüm benim spekülasyonumdur, ancak bu, dil tasarımcılarının API'yi mümkün olduğu kadar temiz tutma arzusunu yansıttığını tahmin ediyorum. Ancak, kontrastı tersine çevirmek, çeşitli ölçütlerle karşılaştırmak, boş değerlerle uğraşmak vb. Tarafından sağlanan çok zengin Comparator yardımcı programına karşı kontrast (bir örnek olarak) ilgimi çeker. Bunlar ayrıca kolayca kullanıcıya bırakılabilir. ancak API tarafından sağlanmıştır. Dil tasarımcılarının birinden, bu arayüzlere yaklaşımların neden bu kadar tutarsız gözüktüğünü duymak isterim.

+0

"Karşılaştırıcı" için yeni şeyler hakkında mükemmel nokta.Zaten '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'işlevini yerine getirerek bir' 'Tüketici'' olarak zaten kullanabilirsiniz. Geri dönüş değeri yok sayılırsa, geri dönüş değeri olmadığında ilk argümanı döndürmekten biraz garip olur. –

+3

Başka bir ses örneği "CompletableFuture" olacaktır, son kez 60 yöntemin yakınında kontrol ettim ... –

+1

Karşılaştırıcıyı zaman içinde gelişen eski bir arabirim olarak düşünmelisiniz. Java8 otoh, fonksiyonel arayüzlere sahip ilk sürümüdür. – the8472

0

Apache commons koleksiyonları 4.x sizin aradığınız öğeye sahiptir, bence. Function ve Consumer için onun eşdeğerleri sırasıyla Transformer ve Closure vardır ve Söz konusu madde, SAM çağırma ve diğer atayarak eşdeğer fonksiyonel türleri arasında dönüştürmek için Önemsiz ClosureTransformer

kullanarak bunları oluşturmak için bir yol sağlar. Hepsini bir araya getirirsek, bir Java 8 bu şekilde Function ile sona erebilir:

Consumer<String> c = System.out::println; 
Function<String,String> f = ClosureTransformer.closureTransformer(c::accept)::transform; 

c::accept eşdeğer Apache Commons 4 Closure için Java 8 Consumer dönüştürür ve son ::transform için Apache Commons 4 Transformer dönüştürür eşdeğer bir Java 8 Function.