Вы можете попытаться получить итератор, а затем создать ленивый список (поток), в котором вы фильтруете (с вашим предикатом) и берете желаемое количество элементов. Поскольку это не строгое, это «взятие» элементов не оценивается.
После этого вы можете принудительно выполнить выполнение, добавив «.par» ко всему этому и достигнув распараллеливания.
Пример кода:
Распараллеленная карта со случайными значениями (имитирующая вашу параллельную хэш-карту):
scala> myMap
res14: scala.collection.parallel.immutable.ParMap[Int,Int] = ParMap(66978401 -> -1331298976, 256964068 -> 126442706, 1698061835 -> 1622679396, -1556333580 -> -1737927220, 791194343 -> -591951714, -1907806173 -> 365922424, 1970481797 -> 162004380, -475841243 -> -445098544, -33856724 -> -1418863050, 1851826878 -> 64176692, 1797820893 -> 405915272, -1838192182 -> 1152824098, 1028423518 -> -2124589278, -670924872 -> 1056679706, 1530917115 -> 1265988738, -808655189 -> -1742792788, 873935965 -> 733748120, -1026980400 -> -163182914, 576661388 -> 900607992, -1950678599 -> -731236098)
Получите итератор и создайте поток из итератора и отфильтруйте его.
В этом случае мой предикат принимает только пары (значения элемента карты).
Я хочу получить 10 четных элементов, поэтому я беру 10 элементов, которые будут оцениваться, только когда я заставлю его:
scala> val mapIterator = myMap.toIterator
mapIterator: Iterator[(Int, Int)] = HashTrieIterator(20)
scala> val r = Stream.continually(mapIterator.next()).filter(_._2 % 2 == 0).take(10)
r: scala.collection.immutable.Stream[(Int, Int)] = Stream((66978401,-1331298976), ?)
Наконец, я вынуждаю оценку, которая получает только 10 элементов, как запланировано
scala> r.force
res16: scala.collection.immutable.Stream[(Int, Int)] = Stream((66978401,-1331298976), (256964068,126442706), (1698061835,1622679396), (-1556333580,-1737927220), (791194343,-591951714), (-1907806173,365922424), (1970481797,162004380), (-475841243,-445098544), (-33856724,-1418863050), (1851826878,64176692))
Таким образом, вы получаете только желаемое количество элементов (без необходимости обработки оставшихся элементов) и распараллеливаете процесс без блокировок, атомизации или разрывов.
Пожалуйста, сравните это с вашими решениями, чтобы увидеть, насколько это хорошо.