2015-08-26 2 views
1

У меня есть Collection с закодированными объектами (которые являются довольно большими, когда не закодированы) и мне было интересно, что происходит на самом деле, если бы я сделал что-то вроде:Что делает parallelstream(). Map(). Map() do?

codes.parallelStream().map(code -> decode(code)).map(obj -> do1(obj) * do2(obj)); 

Как я не нашел гораздо больше информации об этом я предполагаю, что это сначала декодирует все элементы и только потом выполняет реальную задачу, но, с другой стороны, было бы логичнее (и полезно для памяти в случае больших объектов) в случае parallelStream, если бы оно выполняло оба карты одновременно для каждого элемента, например, если есть стояние:

codes.parallelStream().map(code -> { obj = decode(code); return do1(obj) * do2(obj); }); 

Может ли кто-нибудь помочь мне понять, как это работает?

ответ

2

Оценка: map Операция оценивается лениво. Поэтому операция decode в первом вызове map будет выполняться только в том случае, если кодированный объект оценивается терминальной операцией Stream. Поэтому ваше предположение I suppose this first decodes all elements and only afterwards performs the real task неверно, поскольку для работы терминала может потребоваться только несколько элементов исходной коллекции, поэтому ни одна из операций 2 map не будет выполнена для большинства закодированных элементов в этом случае.

Промежуточная операция потока может быть обработана для всех элементов Потока только в том случае, если для этого требуются все элементы (например, sorted()10 необходимо перебирать все элементы) или если она предшествует промежуточной операции, для которой требуются все элементы (например, в ...map().sorted()..., выполнение sorted() требует сначала выполнения map() по всем элементам потока).

Ваши два фрагмента кода должны вести себя аналогичным образом, хотя первый из них более читабельным.

+0

Спасибо, но если я соберу результаты моих двух карт, чтобы их хранить в новой коллекции, например, они будут оценены, правильно? –

+1

@MrTsjolder Да, но каждый исходный объект будет оцениваться по всем методам конвейера Stream до того, как объект будет оцениваться в том же потоке. Поэтому, если ваш параллельный поток использует 2 потока для выполнения конвейера, каждый поток завершит обработку одного закодированного объекта (т. Е. Выполнит вызовы 'map()'), прежде чем переходить к следующему. – Eran