2016-04-11 51 views
0

我會好奇地知道如何將變量傳播到java 8中的流中。 一個例子比長時間的解釋更好,那麼如何將以下(抽象)代碼轉換成流:如何在java中傳播流中的變量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()); 
    } 
} 

知道,這個例子是問題的一個簡化(例如,我需要「參數1」不止一次的下一個for循環)

到目前爲止,唯一的想法我必須將我需要的所有信息存儲到一個元組中,以最終在這個元組上使用forEach流方法。 (不確定是非常清楚....)

編輯:我簡化了我的例子太多。我的情況是比較類似的東西:

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

我可以寫類似的東西與流「)e.getValue.getParam2(」

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

但是,我有什麼,而不是我的真實情況要複雜得多(一個5-6個方法的序列),並且比檢索一個變量(它執行一些邏輯)要重得多,所以我想避免重複e.getValue.getParam2(在forEach之前一次),並且一次在forEach)

我知道這可能不是最好的使用情況下使用流,但我正在瞭解它,並想知道有關限制

謝謝!

+1

嘗試將其更改爲流可能沒有任何優勢。 – Kayaman

回答

1

像這樣:

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

也就是說,對於每個鍵/值對,遍歷value.getParam2()。對於其中的每一個,按照指定格式打印出字符串。我不確定那會得到什麼,除了基本上是你以前的東西,而是使用流。

更新

響應更新你的問題,這樣的:

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

這裏我們分配的getParam2()到最後一個變量的結果,所以只計算一次。最終(和effectively final)變量在lambda函數中可見。

(謝謝霍爾格您的建議。)

+0

謝謝!我簡化了我的案例,我更新了我的帖子,現在我想我更好地解釋了情況 – Jitsumi

+0

非常感謝!這正是我想知道的^^ – Jitsumi

+0

在你的第二個代碼片段中,你仍然調用'e.getValue()。getParam2()'兩次。順便說一下,如果你要處理'Collection'流是'forEach',你根本不需要流,即不用'myMap.entrySet()。stream()。forEach (e - > ...''你可以簡單地使用'myMap.entrySet()。forEach(e - > ...',但是在地圖的情況下,你甚至可以進一步簡化它:myMap.forEach((key,value) - > ... '刪除了處理'Map.Entry'的負擔,調用'getKey()'和'getValue()',總共... – Holger

0

注意,有更多特性的Java API 8比只是流。尤其是,如果您只想處理集合的所有元素,則不需要流。

您可以將每種形式的coll.stream().forEach(consumer)簡化爲coll.forEach(consumer)。這適用於map.entrySet()爲好,但是,如果你想處理Map的所有映射,您可以使用forEach on the Map直接提供BiConsumer<KeyType,ValueType>而非Consumer<Map.Entry<KeyType,ValueType>>,這樣可以大大提高可讀性:

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

值得考慮將forEach(Consumer<ElementType>)方法添加到您的CustomList,即使CustomList不支持其他標準收集操作...

+0

謝謝! 這只是一個簡單的例子,這可能太簡單了,我真正想知道的是如何在流中存儲「複雜」計算以便多次重用它(param2不一定是自定義列表,它可能有點像param2 = value .getA()。getB().calc(value.getParam1())。getC等... 你不想在流中到處重複的東西 但是,我不知道map.forEach,謝謝! – Jitsumi