2014-03-05 2 views
6

각 요소에 대해 각 목록의 i에 대해 작업을 수행합니다. 요소는 임의의 순서로 처리 될 수 있습니다. 오래된 자바 예를 들면 : 그래서 요소를 병렬로 처리 할 수 ​​java.util.stream.Stream와이를 구현하는 가장 좋은 방법입니다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(); 
} 

?

답변

10

목록을 모두 스트리밍 할 수 있다고 생각하지 않도록 두 목록을 병렬로 작업해야합니다. 당신이 인덱스를 스트리밍하고 작업 할 수 있습니다 그러나 : Stream이 새로운

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

해서 당신이 자바가 제공하는 대한 다른 모든 도구를 잊어 버린 것을 의미하지 않는다. 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입니다. 차이점은 조건부 코드가 필요하지 않지만 몇 줄의 추가 선은 해를 입지 않는다는 것입니다. 하지만 나는 그것을 보완하는 솔루션을 넘어서고 싶지 않았습니다. – Holger

+0

죄송합니다. 제가 '라이브러리'라고 말했을 때 저는'java.util.stream' 패키지를 사용했습니다. 나는 당신의 솔루션이 자바 표준 API를 사용한다는 것에 동의한다. 그러나'Stream'이 이미 동시성을 제공한다고 생각하기 때문에 개인적으로'Executor'를 중복 사용한다고 생각합니다.하지만 그건 제 의견입니다. 너를 괴롭히는 것을 의미하지 않았다. @Holger. –