@@ -210,16 +210,16 @@ trait StreamExtensions {
210210 // toScala for streams
211211
212212 implicit class StreamHasToScala [A ](stream : Stream [A ]) {
213- def accumulate : AnyAccumulator [A ] = toScala (Accumulator )
213+ def accumulate : AnyAccumulator [A ] = toScalaFactory (Accumulator )
214214
215215
216216 /**
217217 * Copy the elements of this stream into a Scala collection.
218218 *
219- * Converting a parallel streams to an [[Accumulator ]] using `stream.toScala (Accumulator)`
219+ * Converting a parallel streams to an [[Accumulator ]] using `stream.toScalaFactory (Accumulator)`
220220 * builds the result in parallel.
221221 *
222- * A `toScala (Accumulator)` call automatically converts streams of boxed integers, longs or
222+ * A `toScalaFactory (Accumulator)` call automatically converts streams of boxed integers, longs or
223223 * doubles are converted to the primitive accumulators ([[IntAccumulator ]], etc.).
224224 *
225225 * When converting a parallel stream to a different Scala collection, the stream is first
@@ -230,57 +230,75 @@ trait StreamExtensions {
230230 * Sequential streams are directly converted to the target collection. If the target collection
231231 * is lazy, the conversion is lazy as well.
232232 */
233- def toScala [C1 ](factory : collection.Factory [A , C1 ])(implicit info : AccumulatorFactoryInfo [A , C1 ]): C1 = {
234-
233+ private [java8] def toScalaFactory [C ](factory : collection.Factory [A , C ])(implicit info : AccumulatorFactoryInfo [A , C ]): C = {
235234 def anyAcc = stream.collect(AnyAccumulator .supplier[A ], AnyAccumulator .adder[A ], AnyAccumulator .merger[A ])
236- if (info.companion == AnyAccumulator ) anyAcc.asInstanceOf [C1 ]
237- else if (info.companion == IntAccumulator ) stream.asInstanceOf [Stream [Int ]].collect(IntAccumulator .supplier, IntAccumulator .boxedAdder, IntAccumulator .merger).asInstanceOf [C1 ]
238- else if (info.companion == LongAccumulator ) stream.asInstanceOf [Stream [Long ]].collect(LongAccumulator .supplier, LongAccumulator .boxedAdder, LongAccumulator .merger).asInstanceOf [C1 ]
239- else if (info.companion == DoubleAccumulator ) stream.asInstanceOf [Stream [Double ]].collect(DoubleAccumulator .supplier, DoubleAccumulator .boxedAdder, DoubleAccumulator .merger).asInstanceOf [C1 ]
235+ if (info.companion == AnyAccumulator ) anyAcc.asInstanceOf [C ]
236+ else if (info.companion == IntAccumulator ) stream.asInstanceOf [Stream [Int ]].collect(IntAccumulator .supplier, IntAccumulator .boxedAdder, IntAccumulator .merger).asInstanceOf [C ]
237+ else if (info.companion == LongAccumulator ) stream.asInstanceOf [Stream [Long ]].collect(LongAccumulator .supplier, LongAccumulator .boxedAdder, LongAccumulator .merger).asInstanceOf [C ]
238+ else if (info.companion == DoubleAccumulator ) stream.asInstanceOf [Stream [Double ]].collect(DoubleAccumulator .supplier, DoubleAccumulator .boxedAdder, DoubleAccumulator .merger).asInstanceOf [C ]
240239 else if (stream.isParallel) anyAcc.to(factory)
241240 else factory.fromSpecific(stream.iterator.asScala)
242241 }
243242
243+ /**
244+ * Copy the elements of this stream into a Scala collection.
245+ *
246+ * For parallel streams, using [[accumulate ]] is recommended as it builds the [[Accumulator ]]
247+ * in parallel.
248+ *
249+ * When converting a parallel stream to a different Scala collection, the stream is first
250+ * converted into an [[Accumulator ]], which supports parallel building. The accumulator is
251+ * then converted to the target collection. Note that the stream is processed eagerly while
252+ * building the accumulator, even if the target collection is lazy.
253+ *
254+ * Sequential streams are directly converted to the target collection. If the target collection
255+ * is lazy, the conversion is lazy as well.
256+ */
257+ def toScala [CC [_]](implicit factory : collection.Factory [A , CC [A ]]): CC [A ] = {
258+ if (stream.isParallel) toScalaFactory(Accumulator ).to(factory)
259+ else factory.fromSpecific(stream.iterator.asScala)
260+ }
261+
244262 /** Convert a generic Java Stream wrapping a primitive type to a corresponding primitive
245263 * Stream.
246264 */
247265 def unboxed [S ](implicit unboxer : StreamUnboxer [A , S ]): S = unboxer(stream)
248266 }
249267
250268 implicit class StreamIntHasAccumulatePrimitive (s : Stream [Int ]) {
251- def accumulatePrimitive : IntAccumulator = s.toScala (Accumulator )
269+ def accumulatePrimitive : IntAccumulator = s.toScalaFactory (Accumulator )
252270 }
253271
254272 implicit class StreamLongHasAccumulatePrimitive (s : Stream [Long ]) {
255- def accumulatePrimitive : LongAccumulator = s.toScala (Accumulator )
273+ def accumulatePrimitive : LongAccumulator = s.toScalaFactory (Accumulator )
256274 }
257275
258276 implicit class StreamDoubleHasAccumulatePrimitive (s : Stream [Double ]) {
259- def accumulatePrimitive : DoubleAccumulator = s.toScala (Accumulator )
277+ def accumulatePrimitive : DoubleAccumulator = s.toScalaFactory (Accumulator )
260278 }
261279
262280 implicit class StreamJIntegerHasAccumulatePrimitive (s : Stream [java.lang.Integer ]) {
263- def accumulatePrimitive : IntAccumulator = s.toScala (Accumulator )
281+ def accumulatePrimitive : IntAccumulator = s.toScalaFactory (Accumulator )
264282 }
265283
266284 implicit class StreamJLongHasAccumulatePrimitive (s : Stream [java.lang.Long ]) {
267- def accumulatePrimitive : LongAccumulator = s.toScala (Accumulator )
285+ def accumulatePrimitive : LongAccumulator = s.toScalaFactory (Accumulator )
268286 }
269287
270288 implicit class StreamJDoubleHasAccumulatePrimitive (s : Stream [java.lang.Double ]) {
271- def accumulatePrimitive : DoubleAccumulator = s.toScala (Accumulator )
289+ def accumulatePrimitive : DoubleAccumulator = s.toScalaFactory (Accumulator )
272290 }
273291
274292 implicit class IntStreamHasToScala (stream : IntStream ) {
275- def accumulate : IntAccumulator = toScala (IntAccumulator )
293+ def accumulate : IntAccumulator = toScalaFactory (IntAccumulator )
276294
277295 /**
278296 * Copy the elements of this stream into a Scala collection.
279297 *
280- * Converting a parallel streams to an [[Accumulator ]] using `stream.toScala (Accumulator)`
298+ * Converting a parallel streams to an [[Accumulator ]] using `stream.toScalaFactory (Accumulator)`
281299 * builds the result in parallel.
282300 *
283- * A `toScala (Accumulator)` call automatically converts the `IntStream` to a primitive
301+ * A `toScalaFactory (Accumulator)` call automatically converts the `IntStream` to a primitive
284302 * [[IntAccumulator ]].
285303 *
286304 * When converting a parallel stream to a different Scala collection, the stream is first
@@ -291,25 +309,44 @@ trait StreamExtensions {
291309 * Sequential streams are directly converted to the target collection. If the target collection
292310 * is lazy, the conversion is lazy as well.
293311 */
294- def toScala [ C1 ](factory : collection.Factory [Int , C1 ])(implicit info : AccumulatorFactoryInfo [Int , C1 ]): C1 = {
312+ private [java8] def toScalaFactory [ C ](factory : collection.Factory [Int , C ])(implicit info : AccumulatorFactoryInfo [Int , C ]): C = {
295313 def intAcc = stream.collect(IntAccumulator .supplier, IntAccumulator .adder, IntAccumulator .merger)
296- if (info.companion == AnyAccumulator ) stream.collect(AnyAccumulator .supplier[Int ], AnyAccumulator .unboxedIntAdder, AnyAccumulator .merger[Int ]).asInstanceOf [C1 ]
297- else if (info.companion == IntAccumulator ) intAcc.asInstanceOf [C1 ]
314+ if (info.companion == AnyAccumulator ) stream.collect(AnyAccumulator .supplier[Int ], AnyAccumulator .unboxedIntAdder, AnyAccumulator .merger[Int ]).asInstanceOf [C ]
315+ else if (info.companion == IntAccumulator ) intAcc.asInstanceOf [C ]
298316 else if (stream.isParallel) intAcc.to(factory)
299317 else factory.fromSpecific(stream.iterator.asInstanceOf [java.util.Iterator [Int ]].asScala)
300318 }
319+
320+ /**
321+ * Copy the elements of this stream into a Scala collection.
322+ *
323+ * For parallel streams, using [[accumulate ]] is recommended as it builds the [[IntAccumulator ]]
324+ * in parallel.
325+ *
326+ * When converting a parallel stream to a different Scala collection, the stream is first
327+ * converted into an [[Accumulator ]], which supports parallel building. The accumulator is
328+ * then converted to the target collection. Note that the stream is processed eagerly while
329+ * building the accumulator, even if the target collection is lazy.
330+ *
331+ * Sequential streams are directly converted to the target collection. If the target collection
332+ * is lazy, the conversion is lazy as well.
333+ */
334+ def toScala [CC [_]](implicit factory : collection.Factory [Int , CC [Int ]]): CC [Int ] = {
335+ if (stream.isParallel) toScalaFactory(IntAccumulator ).to(factory)
336+ else factory.fromSpecific(stream.iterator.asInstanceOf [java.util.Iterator [Int ]].asScala)
337+ }
301338 }
302339
303340 implicit class LongStreamHasToScala (stream : LongStream ) {
304- def accumulate : LongAccumulator = toScala (LongAccumulator )
341+ def accumulate : LongAccumulator = toScalaFactory (LongAccumulator )
305342
306343 /**
307344 * Copy the elements of this stream into a Scala collection.
308345 *
309- * Converting a parallel streams to an [[Accumulator ]] using `stream.toScala (Accumulator)`
346+ * Converting a parallel streams to an [[Accumulator ]] using `stream.toScalaFactory (Accumulator)`
310347 * builds the result in parallel.
311348 *
312- * A `toScala (Accumulator)` call automatically converts the `LongStream` to a primitive
349+ * A `toScalaFactory (Accumulator)` call automatically converts the `LongStream` to a primitive
313350 * [[LongAccumulator ]].
314351 *
315352 * When converting a parallel stream to a different Scala collection, the stream is first
@@ -320,25 +357,44 @@ trait StreamExtensions {
320357 * Sequential streams are directly converted to the target collection. If the target collection
321358 * is lazy, the conversion is lazy as well.
322359 */
323- def toScala [ C1 ](factory : collection.Factory [Long , C1 ])(implicit info : AccumulatorFactoryInfo [Long , C1 ]): C1 = {
360+ private [java8] def toScalaFactory [ C ](factory : collection.Factory [Long , C ])(implicit info : AccumulatorFactoryInfo [Long , C ]): C = {
324361 def longAcc = stream.collect(LongAccumulator .supplier, LongAccumulator .adder, LongAccumulator .merger)
325- if (info.companion == AnyAccumulator ) stream.collect(AnyAccumulator .supplier[Long ], AnyAccumulator .unboxedLongAdder, AnyAccumulator .merger[Long ]).asInstanceOf [C1 ]
326- else if (info.companion == LongAccumulator ) longAcc.asInstanceOf [C1 ]
362+ if (info.companion == AnyAccumulator ) stream.collect(AnyAccumulator .supplier[Long ], AnyAccumulator .unboxedLongAdder, AnyAccumulator .merger[Long ]).asInstanceOf [C ]
363+ else if (info.companion == LongAccumulator ) longAcc.asInstanceOf [C ]
327364 else if (stream.isParallel) longAcc.to(factory)
328365 else factory.fromSpecific(stream.iterator.asInstanceOf [java.util.Iterator [Long ]].asScala)
329366 }
367+
368+ /**
369+ * Copy the elements of this stream into a Scala collection.
370+ *
371+ * For parallel streams, using [[accumulate ]] is recommended as it builds the [[LongAccumulator ]]
372+ * in parallel.
373+ *
374+ * When converting a parallel stream to a different Scala collection, the stream is first
375+ * converted into an [[Accumulator ]], which supports parallel building. The accumulator is
376+ * then converted to the target collection. Note that the stream is processed eagerly while
377+ * building the accumulator, even if the target collection is lazy.
378+ *
379+ * Sequential streams are directly converted to the target collection. If the target collection
380+ * is lazy, the conversion is lazy as well.
381+ */
382+ def toScala [CC [_]](implicit factory : collection.Factory [Long , CC [Long ]]): CC [Long ] = {
383+ if (stream.isParallel) toScalaFactory(LongAccumulator ).to(factory)
384+ else factory.fromSpecific(stream.iterator.asInstanceOf [java.util.Iterator [Long ]].asScala)
385+ }
330386 }
331387
332388 implicit class DoubleStreamHasToScala (stream : DoubleStream ) {
333- def accumulate : DoubleAccumulator = toScala (DoubleAccumulator )
389+ def accumulate : DoubleAccumulator = toScalaFactory (DoubleAccumulator )
334390
335391 /**
336392 * Copy the elements of this stream into a Scala collection.
337393 *
338- * Converting a parallel streams to an [[Accumulator ]] using `stream.toScala (Accumulator)`
394+ * Converting a parallel streams to an [[Accumulator ]] using `stream.toScalaFactory (Accumulator)`
339395 * builds the result in parallel.
340396 *
341- * A `toScala (Accumulator)` call automatically converts the `DoubleStream` to a primitive
397+ * A `toScalaFactory (Accumulator)` call automatically converts the `DoubleStream` to a primitive
342398 * [[DoubleAccumulator ]].
343399 *
344400 * When converting a parallel stream to a different Scala collection, the stream is first
@@ -349,13 +405,32 @@ trait StreamExtensions {
349405 * Sequential streams are directly converted to the target collection. If the target collection
350406 * is lazy, the conversion is lazy as well.
351407 */
352- def toScala [ C1 ](factory : collection.Factory [Double , C1 ])(implicit info : AccumulatorFactoryInfo [Double , C1 ]): C1 = {
408+ private [java8] def toScalaFactory [ C ](factory : collection.Factory [Double , C ])(implicit info : AccumulatorFactoryInfo [Double , C ]): C = {
353409 def doubleAcc = stream.collect(DoubleAccumulator .supplier, DoubleAccumulator .adder, DoubleAccumulator .merger)
354- if (info.companion == AnyAccumulator ) stream.collect(AnyAccumulator .supplier[Double ], AnyAccumulator .unboxedDoubleAdder, AnyAccumulator .merger[Double ]).asInstanceOf [C1 ]
355- else if (info.companion == DoubleAccumulator ) doubleAcc.asInstanceOf [C1 ]
410+ if (info.companion == AnyAccumulator ) stream.collect(AnyAccumulator .supplier[Double ], AnyAccumulator .unboxedDoubleAdder, AnyAccumulator .merger[Double ]).asInstanceOf [C ]
411+ else if (info.companion == DoubleAccumulator ) doubleAcc.asInstanceOf [C ]
356412 else if (stream.isParallel) doubleAcc.to(factory)
357413 else factory.fromSpecific(stream.iterator.asInstanceOf [java.util.Iterator [Double ]].asScala)
358414 }
415+
416+ /**
417+ * Copy the elements of this stream into a Scala collection.
418+ *
419+ * For parallel streams, using [[accumulate ]] is recommended as it builds the [[DoubleAccumulator ]]
420+ * in parallel.
421+ *
422+ * When converting a parallel stream to a different Scala collection, the stream is first
423+ * converted into an [[Accumulator ]], which supports parallel building. The accumulator is
424+ * then converted to the target collection. Note that the stream is processed eagerly while
425+ * building the accumulator, even if the target collection is lazy.
426+ *
427+ * Sequential streams are directly converted to the target collection. If the target collection
428+ * is lazy, the conversion is lazy as well.
429+ */
430+ def toScala [CC [_]](implicit factory : collection.Factory [Double , CC [Double ]]): CC [Double ] = {
431+ if (stream.isParallel) toScalaFactory(DoubleAccumulator ).to(factory)
432+ else factory.fromSpecific(stream.iterator.asInstanceOf [java.util.Iterator [Double ]].asScala)
433+ }
359434 }
360435}
361436
0 commit comments