• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Junilu Lacar
Sheriffs:
  • Rob Spoor
  • Liutauras Vilda
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Piet Souris
  • Tim Holloway
  • Jj Roberts
  • Stephan van Hulst
Bartenders:
  • Himai Minh
  • Carey Brown
  • Frits Walraven

Errata in OCP study guide ? (Sybex)

 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,
On page 204 about streams, table 4.5 says that this is non destructive :


It seems to me as destructive, since the stream can no longer be used afterwards.
Maybe this one would be non destructive :


cheers
 
Marshal
Posts: 73334
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

Please provide more details of the book, including authors' names.
What is the definition of a non‑destructive operation?
What do you think would happen if you execute your second code block?
 
Marshal
Posts: 16456
272
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I believe you're right, since count() is a terminating operation
 
author & internet detective
Posts: 40685
827
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm pretty sure that's my book as this is a question we get periodically. The point we are trying to make is that the printing (peek operation) is not destructive.

Yes, count() is a terminal operation. You need a terminal operation to do anything. But printing isn't 'using" up the stream. Counting is.
 
Junilu Lacar
Marshal
Posts: 16456
272
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't think "destructive" and "non-destructive" are even the right terms to use here. The API documentation refers to these as intermediate and terminal operations. Even an intermediate operation like peek consumes the stream it operates on and produces a new stream so I'm not sure what we're referring to here as being "not destroyed" or otherwise.

For example, you can't do this:

Because that would produce this exception:
java.lang.IllegalStateException: stream has already been operated upon or closed

Also, starting from Java 9 onwards, the line in question will not even produce any output (at least not when I ran it using different versions of the JDK on my Mac).
 
Junilu Lacar
Marshal
Posts: 16456
272
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Starting from Java 9, the API documentation for Stream.count() has this note (emphasis on last line mine):

API Note:
An implementation may choose to not execute the stream pipeline (either sequentially or in parallel) if it is capable of computing the count directly from the stream source. In such cases no source elements will be traversed and no intermediate operations will be evaluated. Behavioral parameters with side-effects, which are strongly discouraged except for harmless cases such as debugging, may be affected. For example, consider the following stream:

    List<String> l = Arrays.asList("A", "B", "C", "D");
    long count = l.stream().peek(System.out::println).count();


The number of elements covered by the stream source, a List, is known and the intermediate operation, peek, does not inject into or remove elements from the stream (as may be the case for flatMap or filter operations). Thus the count is the size of the List and there is no need to execute the pipeline and, as a side-effect, print out the list elements.

 
Campbell Ritchie
Marshal
Posts: 73334
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That actually means its behaviour is not strictly defined, and it differs in Java9 from Java8.
 
Campbell Ritchie
Marshal
Posts: 73334
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I had a quick scan through Stream's methods and count() appears to be the only method where the API note suggests any such difference in behaviour.
 
Campbell Ritchie
Marshal
Posts: 73334
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:Starting from Java 9 . . .

Since this question has arisen again, I thought I would let JShell (preissue JDK14 version) have a go at it:-

Campbell's JShell (minus the mistakes) wrote:jshell> List<Integer> numbers = new ArrayList<>();
numbers ==> []

jshell> numbers.add(1);
$5 ==> true

jshell> System.out.println(numbers.stream().peek(System.out::println).count());
1

jshell> numbers.add(999);
$7 ==> true

jshell> System.out.println(numbers.stream().peek(System.out::println).count());
2

No sign of peek() being called. Does anybody know whether the JVM is optimising the stream away entirely and telescoping the process to ...numbers.size()...?
 
reply
    Bookmark Topic Watch Topic
  • New Topic