Rule 3864 "Stream.peek should not be used": improving title and description

java

(Jens Bannmann) #1

Hi all,

the recently introduced rule about Stream.peek() works fine, but its current title and description lack detail:


“Stream.peek” should not be used

Labels: none

According to the JavaDocs java.util.Stream.peek is only meant to be used for debugging purposes and should not be used in production.

Noncompliant Code Example

Stream.of("one", "two", "three", "four")
         .filter(e -> e.length() > 3)
         .peek(e -> System.out.println("Filtered value: " + e)); // Noncompliant

See

Java 8 API Documentation


Compared to other rules, this description does not give much rationale, background or advice. Also, its title is slightly misleading: “debugging purposes” does not really imply “should not be used in production” as production code certainly can have logging calls which are useful for debugging.

I suggest the following title, labels and description instead:


“Stream.peek” should be used with caution

Labels: +pitfall, +java8

According to its JavaDocs, java.util.Stream.peek() “exists mainly to support debugging” purposes. While non-debugging usages are neither forbidden nor discouraged, relying on peek() without careful consideration can lead to error-prone code due to its subtleties:

  • If the stream pipeline neither includes a terminal operation nor a stateful intermediate operation, no elements may be consumed at all, so the action will not be invoked.
  • In cases where the stream implementation is able to optimize away the production of some or all the elements (such as with short-circuiting operations like findFirst, or in certain situations with count), the action will not be invoked for those elements.

This rule raises an issue for each use of peek() to be sure that it is challenged and validated by the team to be meant for production debugging/logging purposes and/or is not affected by the subtleties given above.

Noncompliant Code Example

Stream.of("one", "two", "three", "four")
         .filter(e -> e.length() > 3)
         .peek(e -> System.out.println("Filtered value: " + e)); // Noncompliant

See

Notes


Please consider using the text above or parts of it. If nothing else, I suggest adding the Idiomatic Peeking with Java Stream API link to the existing rule description.

Best regards,
Jens