2016-04-05 33 views
6

Etkili Java 2. Ed'e göre, varargs'e izin veren bir yöntem imzası yazmak istediğinizde ancak derleme zamanında en az bir öğeye sahip olduğunuzu zorlarsanız, yöntem imzasını bu şekilde yazmanız gerekir. Ben 1 akışı oluşturuyorsam özellikle çünküJava 8 akışları ve varargs

public void something(String required, String ... additional) { 
    Stream<String> allParams = 
     Stream.concat(Stream.of(required), Stream.of(additional)); 
    //... do what you want to do 
} 

Bu gerçekten inelegant ve savurgan hisseder: bütün bu unsurları akarsu isterseniz

public void something(String required, String ... additional) { 
    //... do what you want to do 
} 

, böyle bir şey yapıyorum ve concatena Bir diğeriyle bağla. Bunu yapmanın daha temiz bir yolu var mı?

+5

'Stream.concat' iyi gibi geliyor bana .. Kısa, özlü, verilerin kopyalarını oluşturmuyor. Birkaç ekstra sarıcı nesne oluşturuyorsunuz, hepsi bu. IMO gerçekten onunla yanlış bir şey yok. Java'da programlama, sadece burada ve orada şeyler için küçük nesneler oluşturmanız gerekir. "Stream.concat", onları bir "ArrayList" ile birleştirmekten çoktan uzaktaydı. – Radiodef

+1

Radiodef ile aynı fikirdeyim, eğer gerçekten istiyorsan, Spliterator 'kendi uygulamanızı yapabilir ve onu StreamSupport.stream (spliterator, parallel) ile kullanabilirsin ama gerçekten daha fazla okunabilir veya verimli hale gelebilirmiş gibi hissetmiyorum. . –

cevap

6

İki Streams oluşturmadan bunu yapmanın bir yolu.

Stream.Builder<String> builder = Stream.<String>builder().add(required); 
for (String s : additional) { 
    builder.add(s); 
} 

Stream<String> allParams = builder.build(); 
+0

Ayrıca for döngüsünü "Stream.of (ek) .forEach (oluşturucu)" ile de değiştirebilirsiniz; –

+0

Bunu tekrar gözden geçirdikten ve yorumlara dayanarak, orijinal yolum iyi görünüyor. Ancak, bu cevap önceki görüşüme göre en iyi alternatif olarak görünüyor. Teşekkürler :) –

1

Eğer Guava kullanmaya istekli iseniz, olabilir Lists.asList(required, additional).stream(). Yöntem, minimum gereksinim deyimiyle varargları kolaylaştırmak için oluşturuldu.

Bir yan not, kütüphaneyi gerçekten yararlı buluyorum, ama tabiki bunun için eklemek iyi bir fikir değil. docs'u kontrol edin ve size daha fazla kullanım olup olmadığını kontrol edin.

2

Ne yazık ki, Java oldukça ayrıntılı olabilir. Ancak bunu hafifletmek için başka bir seçenek de statik ithalatı kullanmaktır. Benim düşünceme göre, her yöntem akışla ilgili olduğundan kodunuzu daha az netleştirmez. oluşan akışları ile yanlış bir şey yok

Stream<String> allParams = 
    concat(of(required), of(additional)); 
1

. Bu nesneler, yalnızca kaynak verilere başvurdukları, ancak dizi içeriği gibi verileri kopyalamadıkları için hafiftir. Bu hafif nesnenin maliyeti sadece gerçek yükün de çok küçük olması durumunda uygun olabilir. Böyle senaryolar uzman, anlama sahip aşırı ele alınabilir:

public void something(String required, String ... additional) { 
    somethingImpl(Stream.concat(Stream.of(required), Stream.of(additional))); 
} 
public void something(String required) { 
    somethingImpl(Stream.of(required)); 
} 
public void something(String required, String second) { 
    somethingImpl(Stream.of(required, second)); 
} 
private void somethingImpl(Stream<String> allParams) { 
    //... do what you want to do 
} 

böylece sadece Stream örneklerini değil, aynı zamanda (Stream.of ‘ın aşırı benzer) varargs dizi tasarruf değil sadece bir argüman durumunda. Bu yaygın bir modeldir, örneğin EnumSet.of aşırı yüklerine bakın. Bununla birlikte, birçok durumda, bu basit aşırı yüklemeler bile gerekli değildir ve erken optimizasyon olarak kabul edilebilir (JRE gibi kütüphaneler, bir uygulama geliştiricisinin bunları gerektiğinde eklemek için olanaksız hale gelmesi nedeniyle mümkün değildir). something bir kitaplıktan ziyade bir uygulamanın parçasıysa, bir profiler size bu parametre işlemenin neden olduğu bir darboğaz olmadığını bildirmedikçe eklememelisiniz.

1

Üçüncü taraf uzantıları benim StreamEx veya jOOλappend ya da daha temiz bir şekilde bunu yapmak için izin prepend gibi yöntemler sağlamak gibi API Stream:

// Using StreamEx 
Stream<String> allParams = StreamEx.of(required).append(additional); 
// Using jOOL 
Stream<String> allParams = Seq.of(required).append(additional);