2014-03-05 45 views
6

對於每個列表中的每個元素i執行操作。元素可以按任何順序處理。例如,在舊的Java:與java.util.stream.Stream並行處理兩個列表

List<A> aList; 
List<B> bList; // aList is larger than bList 

for (int i=0; i<bList.size(), i++) { 
    aList.get(i).doSomethingWith(bList.get(i)); 
} 

for (int j=i; j<aList.size(), j++) { 
    aList.get(j).doSomething(); 
} 

這與java.util.stream.Stream所以元素可以被並行處理來實現這一目標的最佳方式是什麼?

回答

10

你需要並行處理兩個列表,所以我不認爲你可以自己流列表。然而,你可以流指標和關於工作:

IntStream.range(0, aList.size()) 
    .parallel() 
    .forEach(i -> { 
     if (i < bList.size()) aList.get(i).doSomethingWith(bList.get(i)); 
     else aList.get(i).doSomething(); 
    }); 
+0

謝謝,正是我所需要的。 –

5

只是因爲Stream是新的,這並不意味着你應該忘記其他所有工具Java提供。即使使用這些優秀的舊工具,使用Java 8變得更流暢:

List<A> aList; 
List<B> bList; // aList is larger than bList 

ExecutorService exec = Executors.newCachedThreadPool(); 
int a=aList.size(), b=bList.size(); 
assert a>b; 
Future<?> f1=exec.submit(()->IntStream.range(0, b) 
    .parallel().forEach(i->aList.get(i).doSomethingWith(bList.get(i))) 
); 
Future<?> f2=exec.submit(()->aList.subList(b, a) 
    .stream().parallel().forEach(A::doSomething) 
); 
f1.get(); 
f2.get(); 
exec.shutdown(); 
+0

好的解決方案Holger,但我認爲assylias提出了一個更好的方法。它更乾淨,完全依賴於併發庫。 –

+0

@Jose Gisbert:我沒有看到你評論的最後一句話。我的解決方案在哪裏取決於「併發庫」?它是純粹的Java標準API。區別在於它不需要任何條件代碼,而少數額外的行不會造成損害。但我並不想挑戰assylias的解決方案。 – Holger

+0

對不起,當我說'庫'我的意思是'java.util.stream'包。我同意你的解決方案使用Java標準API,因爲這個原因,我對它進行了升級。然而,考慮到'Stream'已經提供了併發性,我個人認爲使用'Executor'是多餘的,但這是我的看法。不是有意冒犯你@霍爾。 –