299 * computation.
300 * </li>
301 * </ul>
302 * <p>The ordering of side-effects may be surprising. Even when a pipeline is
303 * constrained to produce a <em>result</em> that is consistent with the
304 * encounter order of the stream source (for example,
305 * {@code IntStream.range(0,5).parallel().map(x -> x*2).toArray()}
306 * must produce {@code [0, 2, 4, 6, 8]}), no guarantees are made as to the order
307 * in which the mapper function is applied to individual elements, or in what
308 * thread any behavioral parameter is executed for a given element.
309 *
310 * <p>The eliding of side-effects may also be surprising. With the exception of
311 * terminal operations {@link java.util.stream.Stream#forEach forEach} and
312 * {@link java.util.stream.Stream#forEachOrdered forEachOrdered}, side-effects
313 * of behavioral parameters may not always be executed when the stream
314 * implementation can optimize away the execution of behavioral parameters
315 * without affecting the result of the computation. (For a specific example
316 * see the API note documented on the {@link java.util.stream.Stream#count count}
317 * operation.)
318 *
319 * <p>Many computations where one might be tempted to use side effects can be more
320 * safely and efficiently expressed without side-effects, such as using
321 * <a href="package-summary.html#Reduction">reduction</a> instead of mutable
322 * accumulators. However, side-effects such as using {@code println()} for debugging
323 * purposes are usually harmless. A small number of stream operations, such as
324 * {@code forEach()} and {@code peek()}, can operate only via side-effects;
325 * these should be used with care.
326 *
327 * <p>As an example of how to transform a stream pipeline that inappropriately
328 * uses side-effects to one that does not, the following code searches a stream
329 * of strings for those matching a given regular expression, and puts the
330 * matches in a list.
331 *
332 * <pre>{@code
333 * ArrayList<String> results = new ArrayList<>();
334 * stream.filter(s -> pattern.matcher(s).matches())
335 * .forEach(s -> results.add(s)); // Unnecessary use of side-effects!
336 * }</pre>
337 *
338 * This code unnecessarily uses side-effects. If executed in parallel, the
339 * non-thread-safety of {@code ArrayList} would cause incorrect results, and
428 *
429 * <p>These reduction operations can run safely in parallel with almost no
430 * modification:
431 * <pre>{@code
432 * int sum = numbers.parallelStream().reduce(0, Integer::sum);
433 * }</pre>
434 *
435 * <p>Reduction parallellizes well because the implementation
436 * can operate on subsets of the data in parallel, and then combine the
437 * intermediate results to get the final correct answer. (Even if the language
438 * had a "parallel for-each" construct, the mutative accumulation approach would
439 * still required the developer to provide
440 * thread-safe updates to the shared accumulating variable {@code sum}, and
441 * the required synchronization would then likely eliminate any performance gain from
442 * parallelism.) Using {@code reduce()} instead removes all of the
443 * burden of parallelizing the reduction operation, and the library can provide
444 * an efficient parallel implementation with no additional synchronization
445 * required.
446 *
447 * <p>The "widgets" examples shown earlier shows how reduction combines with
448 * other operations to replace for loops with bulk operations. If {@code widgets}
449 * is a collection of {@code Widget} objects, which have a {@code getWeight} method,
450 * we can find the heaviest widget with:
451 * <pre>{@code
452 * OptionalInt heaviest = widgets.parallelStream()
453 * .mapToInt(Widget::getWeight)
454 * .max();
455 * }</pre>
456 *
457 * <p>In its more general form, a {@code reduce} operation on elements of type
458 * {@code <T>} yielding a result of type {@code <U>} requires three parameters:
459 * <pre>{@code
460 * <U> U reduce(U identity,
461 * BiFunction<U, ? super T, U> accumulator,
462 * BinaryOperator<U> combiner);
463 * }</pre>
464 * Here, the <em>identity</em> element is both an initial seed value for the reduction
465 * and a default result if there are no input elements. The <em>accumulator</em>
466 * function takes a partial result and the next element, and produces a new
467 * partial result. The <em>combiner</em> function combines two partial results
468 * to produce a new partial result. (The combiner is necessary in parallel
|
299 * computation.
300 * </li>
301 * </ul>
302 * <p>The ordering of side-effects may be surprising. Even when a pipeline is
303 * constrained to produce a <em>result</em> that is consistent with the
304 * encounter order of the stream source (for example,
305 * {@code IntStream.range(0,5).parallel().map(x -> x*2).toArray()}
306 * must produce {@code [0, 2, 4, 6, 8]}), no guarantees are made as to the order
307 * in which the mapper function is applied to individual elements, or in what
308 * thread any behavioral parameter is executed for a given element.
309 *
310 * <p>The eliding of side-effects may also be surprising. With the exception of
311 * terminal operations {@link java.util.stream.Stream#forEach forEach} and
312 * {@link java.util.stream.Stream#forEachOrdered forEachOrdered}, side-effects
313 * of behavioral parameters may not always be executed when the stream
314 * implementation can optimize away the execution of behavioral parameters
315 * without affecting the result of the computation. (For a specific example
316 * see the API note documented on the {@link java.util.stream.Stream#count count}
317 * operation.)
318 *
319 * <p>Many computations where one might be tempted to use side-effects can be more
320 * safely and efficiently expressed without side-effects, such as using
321 * <a href="package-summary.html#Reduction">reduction</a> instead of mutable
322 * accumulators. However, side-effects such as using {@code println()} for debugging
323 * purposes are usually harmless. A small number of stream operations, such as
324 * {@code forEach()} and {@code peek()}, can operate only via side-effects;
325 * these should be used with care.
326 *
327 * <p>As an example of how to transform a stream pipeline that inappropriately
328 * uses side-effects to one that does not, the following code searches a stream
329 * of strings for those matching a given regular expression, and puts the
330 * matches in a list.
331 *
332 * <pre>{@code
333 * ArrayList<String> results = new ArrayList<>();
334 * stream.filter(s -> pattern.matcher(s).matches())
335 * .forEach(s -> results.add(s)); // Unnecessary use of side-effects!
336 * }</pre>
337 *
338 * This code unnecessarily uses side-effects. If executed in parallel, the
339 * non-thread-safety of {@code ArrayList} would cause incorrect results, and
428 *
429 * <p>These reduction operations can run safely in parallel with almost no
430 * modification:
431 * <pre>{@code
432 * int sum = numbers.parallelStream().reduce(0, Integer::sum);
433 * }</pre>
434 *
435 * <p>Reduction parallellizes well because the implementation
436 * can operate on subsets of the data in parallel, and then combine the
437 * intermediate results to get the final correct answer. (Even if the language
438 * had a "parallel for-each" construct, the mutative accumulation approach would
439 * still required the developer to provide
440 * thread-safe updates to the shared accumulating variable {@code sum}, and
441 * the required synchronization would then likely eliminate any performance gain from
442 * parallelism.) Using {@code reduce()} instead removes all of the
443 * burden of parallelizing the reduction operation, and the library can provide
444 * an efficient parallel implementation with no additional synchronization
445 * required.
446 *
447 * <p>The "widgets" examples shown earlier shows how reduction combines with
448 * other operations to replace for-loops with bulk operations. If {@code widgets}
449 * is a collection of {@code Widget} objects, which have a {@code getWeight} method,
450 * we can find the heaviest widget with:
451 * <pre>{@code
452 * OptionalInt heaviest = widgets.parallelStream()
453 * .mapToInt(Widget::getWeight)
454 * .max();
455 * }</pre>
456 *
457 * <p>In its more general form, a {@code reduce} operation on elements of type
458 * {@code <T>} yielding a result of type {@code <U>} requires three parameters:
459 * <pre>{@code
460 * <U> U reduce(U identity,
461 * BiFunction<U, ? super T, U> accumulator,
462 * BinaryOperator<U> combiner);
463 * }</pre>
464 * Here, the <em>identity</em> element is both an initial seed value for the reduction
465 * and a default result if there are no input elements. The <em>accumulator</em>
466 * function takes a partial result and the next element, and produces a new
467 * partial result. The <em>combiner</em> function combines two partial results
468 * to produce a new partial result. (The combiner is necessary in parallel
|