285 * Side-effects in behavioral parameters to stream operations are, in general, |
285 * Side-effects in behavioral parameters to stream operations are, in general, |
286 * discouraged, as they can often lead to unwitting violations of the |
286 * discouraged, as they can often lead to unwitting violations of the |
287 * statelessness requirement, as well as other thread-safety hazards. |
287 * statelessness requirement, as well as other thread-safety hazards. |
288 * |
288 * |
289 * <p>If the behavioral parameters do have side-effects, unless explicitly |
289 * <p>If the behavioral parameters do have side-effects, unless explicitly |
290 * stated, there are no guarantees as to the |
290 * stated, there are no guarantees as to: |
291 * <a href="../concurrent/package-summary.html#MemoryVisibility"><i>visibility</i></a> |
291 * <ul> |
292 * of those side-effects to other threads, nor are there any guarantees that |
292 * <li>the <a href="../concurrent/package-summary.html#MemoryVisibility"> |
293 * different operations on the "same" element within the same stream pipeline |
293 * <i>visibility</i></a> of those side-effects to other threads;</li> |
294 * are executed in the same thread. Further, the ordering of those effects |
294 * <li>that different operations on the "same" element within the same stream |
295 * may be surprising. Even when a pipeline is constrained to produce a |
295 * pipeline are executed in the same thread; and</li> |
296 * <em>result</em> that is consistent with the encounter order of the stream |
296 * <li>that behavioral parameters are always invoked, since a stream |
297 * source (for example, {@code IntStream.range(0,5).parallel().map(x -> x*2).toArray()} |
297 * implementation is free to elide operations (or entire stages) from a |
|
298 * stream pipeline if it can prove that it would not affect the result of the |
|
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()} |
298 * must produce {@code [0, 2, 4, 6, 8]}), no guarantees are made as to the order |
306 * must produce {@code [0, 2, 4, 6, 8]}), no guarantees are made as to the order |
299 * in which the mapper function is applied to individual elements, or in what |
307 * in which the mapper function is applied to individual elements, or in what |
300 * thread any behavioral parameter is executed for a given element. |
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.) |
301 * |
318 * |
302 * <p>Many computations where one might be tempted to use side effects can be more |
319 * <p>Many computations where one might be tempted to use side effects can be more |
303 * safely and efficiently expressed without side-effects, such as using |
320 * safely and efficiently expressed without side-effects, such as using |
304 * <a href="package-summary.html#Reduction">reduction</a> instead of mutable |
321 * <a href="package-summary.html#Reduction">reduction</a> instead of mutable |
305 * accumulators. However, side-effects such as using {@code println()} for debugging |
322 * accumulators. However, side-effects such as using {@code println()} for debugging |