Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #33367
| From | Sebastian <news@seyweiler.dyndns.org> |
|---|---|
| Newsgroups | comp.lang.java.programmer |
| Subject | Re: parallel stream ordering |
| Date | 2015-12-18 23:11 +0100 |
| Organization | albasani.net |
| Message-ID | <n520ai$tv8$1@news.albasani.net> (permalink) |
| References | <36e2751f-2deb-49da-8b67-d16ba5196d33@googlegroups.com> <e411aca2-0b19-4de0-8c9f-a99d83dc2b11@googlegroups.com> |
Am 17.12.2015 22:38, schrieb Lew:
> On Wednesday, December 16, 2015 at 11:47:43 PM UTC-8, Philipp Kraus wrote:
>> Hello,
>>
>> I'm using calls like
>>
>> m_annotationexecution.parallelStream().flatMap( i -> i.execute( p_context, null ).stream() ).collect( Collectors.toList() )
>>
>> execute returns a List, so the flatMap enrolls the list elements to collect them into a new list, but I would like to fix the order. For example m_annotation is a list like
>>
>> [ "a", "b", "c" ]
>>
>> execute transform it to
>>
>> a -> ["a", "1", ...]
>> b -> ["b", "2", ...]
>> c -> ["c", "3", ....]
>>
>> the flatMap enrolls it to
>>
>> ["a", "1", ..., "b", "2", ..., "c", "3", ....]
>>
>> but on a parallel stream the order is not fixed, so I can get also
>>
>> ["b", "2", ..., "a", "1", ..., "c", "3", ....] or ["c", "3", ..., "a", "1", ..., "b", "2", ....]
>>
>> So how can I fix the order, so that the first element in m_annotation is also the first element within the result list? execute and flatMap can be run in parallel, but only the collect must create the correct ordering.
>> If Iuse this input [ "a", "b", "c" ] the output should be ["a", "1", ..., "b", "2", ..., "c", "3", ....] during execution the temporal order can be changed
>>
>> Thanks
>>
>> Phil
>
> Quite aside from your question:
> * 'm_annotationexecution' isn't consistent with the Java naming conventions. It should be something like 'annotationExecution'.
> * s/enrolls/unrolls/ - different words with different meanings
>
> You can fix the order by using a 'for' loop instead of streams. Parallelization by its nature wants to disregard order.
>
You have at least two more options here. For one thing, you could use a
library like RxJava, which has a concatMap method on Observables which
as the name suggests concats the lists, while flatMap does a merge.
If you can provide a Comparator on the result elements to define the
desired order, you can simply collect to a sorted list, like
...collect(toSortedList()), where toSortedList may be defined as
private static <T> Collector<T, ?, List<T>> toSortedList(Comparator<T>
order) {
return collectingAndThen(toCollection(ArrayList::new),
(List<T> l) -> {
l.sort(order);
return l;
});
}
The trick is to be sure to collect to a list that can be sorted in situ
(ArrayList in this case). This involves no additional copying, in
contrast to ...sorted().collect(toList()) which would copy the list once
more.
collectingAndThen() is in java.util.stream.Collectors. Know thine API!
-- Sebastian
Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Find similar | Unroll thread
parallel stream ordering Philipp Kraus <philipp.kraus.flashpixx@gmail.com> - 2015-12-16 23:47 -0800
Re: parallel stream ordering Lew <lewbloch@gmail.com> - 2015-12-17 13:38 -0800
Re: parallel stream ordering Sebastian <news@seyweiler.dyndns.org> - 2015-12-18 23:11 +0100
csiph-web