2016-04-11 10 views
0

Java 8'de bir akışa değişkeni nasıl yayılacağını bilmek akıllıca olur. Bir örnek uzun bir açıklamadan daha iyidir, bu yüzden aşağıdakileri nasıl dönüştürürdünüz? akışlarına kodu:Java'da bir akışta değişkenler nasıl yayılır 8

Map<Integer,A> myMap = new HashMap(); 


for (Entry<Integer,A> entry : myMap) 
{ 
    int param1=entry.getValue().getParam1(); 
    List param2=entry.getValue().getParam2(); 
    for (B b : param2) 
    { 
     System.out.println(""+entry.getKey()+"-"+param1+"-"+b.toString()); 
    } 
} 

bu örnek sorunun bir basitleştirme olduğunu bilerek (örneğin, i "param1" ihtiyaç döngü içinde birden fazla kez sonraki)

Şimdiye kadar sadece bir fikir i Bu tuple üzerinden forEach akış yöntemini en sonunda kullanmak için bir tuple ihtiyacım olan tüm bilgileri saklamak zorunda. (Net olmadığından emin olun ....)

Düzenleme: Örneğimi çok fazla basitleştirdim. Ancak

myMap.entrySet().stream() 
    .forEach(
     e -> IntStream.range(0, e.getValue.getParam2().getSize()) 
      .forEach(
       i -> System.out.println(e.getKey()+"-"+e.getValue().getParam1()+"-"+e.getValue.getParam2.get(i)) 
      ) 
    ); 

i yerine ne var "(e.getValue.getParam2)" benim gerçek de:

Map<Integer,A> myMap = new HashMap(); 


for (Entry<Integer,A> entry : myMap) 
{ 
    int param1=entry.getValue().getParam1(); 
    CustomList param2=entry.getValue().getParam2(); 
    for (int i = 0; i<param2.size(); i++) 
    { 
     System.out.println(""+entry.getKey()+"-"+param1+"-"+param2.get(i).toString()); 
    } 
} 

Ben akışıyla böyle bir şeyi yazabilirsiniz: Davam böyle fazlası mı durum çok daha karmaşık (5-6 yöntemli bir dizi) ve sadece bir değişken almaktan daha ağırdır (bazı mantığı yürütür), bu yüzden e.getValue.getParam2'yi tekrarlamaktan kaçınmak istiyorum (bir kere forEach'ten hemen önce, ve forEach)

Bir kez kullanmanın en iyi kullanım durumunun olmadığını biliyorum. stream, ama bu konuda öğreniyorum ve sınırları hakkında bilmek istiyorum

Teşekkürler! Böyle

+1

Akımları bu akışa dönüştürmeye çalışırken herhangi bir avantaj olmayabilir. – Kayaman

cevap

1

şey:

olduğunu
myMap.forEach(
    (key, value) -> value.getParam2().forEach(
     b -> System.out.println(key+"-"+value.getParam1()+"-"+b) 
    ) 
); 

, her anahtar/değer çifti için, value.getParam2() yinelemenize. Bunların her biri için, belirttiğiniz şekilde biçimlendirilmiş dize yazdırın. Seni neye götürdüğünden emin değilim, daha önce sahip olduğunuz şeyden başka, ama akımları kullanmaktan başka. Sorunuzun güncellemeleri yanıtlayan Güncelleme

bu: İşte

myMap.forEach((key, value) -> { 
    final CustomList param2 = value.getParam2(); 
    IntStream.range(0, param2.getSize()).forEach(
     i -> System.out.println(key+"-"+value.getParam1()+"-"+param2.get(i)) 
    ) 
}); 

biz nihai değişkene getParam2() sonucunu atamak, bu yüzden sadece bir kez hesaplanır. Final (ve effectively final) değişkenleri lambda işlevlerinde görülebilir.

(öneriler için Holgeri teşekkür ederiz.) Sadece akışları daha fazla özellik Java 8 API olduğunu

+0

Teşekkürler! Davalarım çok basitleştirdim, mesajımı güncelledim ve şimdi durumu daha iyi açıkladığımı düşünüyorum – Jitsumi

+0

Çok teşekkürler! Tam olarak bilmek istediğim tam olarak budur ^^ – Jitsumi

+0

İkinci kod snippet'inizde hala "e.getValue(). GetParam2()' yi iki kez çağırıyorsunuz. Bu arada, 'Koleksiyon'un akışıyla yapacağınız tek şey' forEach 'ise, hiç bir akışa ihtiyacınız yoktur, yani myMap.entrySet(). Stream(). ForEach (e ->… 'myMap.entrySet(). forEach (e ->…') 'yı kullanabilirsiniz, ancak haritalar durumunda, daha da basitleştirebilirsiniz: myMap.forEach ((key, value) ->… 'getKey()' ve 'getValue()' işlevini 'Map.Entry' ile uğraşmak zorunda kalma yükünü tamamen ortadan kaldırır… – Holger

0

Not. Özellikle, bir koleksiyonun tüm öğelerini işlemek istiyorsanız, akışlara ihtiyacınız yoktur.

coll.stream().forEach(consumer) - coll.forEach(consumer) arasındaki tüm formları basitleştirebilirsiniz.

myMap.forEach((key, value) -> { 
    int  param1 = value.getParam1(); 
    CustomList param2 = value.getParam2(); 
    IntStream.range(0, param2.size()).mapToObj(param2::get) 
     .forEach(obj -> System.out.println(key+"-"+param1+"-"+obj)); 
}); 

Bu değer: Bu, bir Map tüm eşleşmeleri işlemek istiyorsanız, doğrudan forEach on the Map kullanabilirsiniz ölçüde okunabilirliği artırmak hangi bir Consumer<Map.Entry<KeyType,ValueType>> yerine BiConsumer<KeyType,ValueType> sağlayan, ancak, aynı zamanda map.entrySet() için de geçerlidir CustomListCustomList ürününüze forEach(Consumer<ElementType>) yöntemini eklemeyi düşünmek, CustomList diğer standart toplama işlemlerini desteklemese bile…

+0

Teşekkürler! Sadece basit bir örnek, Bu gerçekten çok basit bir şeydi: Gerçekten bilmek istediğim şey, akıştaki "karmaşık" bir hesaplamayı, daha sonra tekrar tekrar kullanmak için depolamaktı. (param2, özel bir liste olmak zorunda değildir, param2 = değer gibi bir şey olabilir) .getA(). getB(). calc (value.getParam1()). getC vb ... Akışta her yerde tekrarlamak istemediğiniz bir şey Ancak haritayı bilmiyordum, teşekkürler! – Jitsumi