• 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
  • Ron McLeod
  • Paul Clapham
  • Rob Spoor
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Tim Holloway
  • Piet Souris
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Frits Walraven
  • Himai Minh

Yikes!! This explanation of .flatMapToInt() .flatMapToDouble() .flatMapToLong() seems very wrong!

 
Bartender
Posts: 1064
33
Eclipse IDE Postgres Database C++ Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have dived head first into Java Streams!!  About time!

On page 218 of the Sybex 816 book by Jeanne & Scott, in the middle of the presentation about Primitive Streams, they have a boxed text called "Using flatMap()"

It seems very wrong to me (but this stuff is still new to me).
The text says:

The flatMap() method exists on primitive streams as well.  It works the same way as on a regular Stream except the method name is different.  Here's an example:

var integerList = new ArrayList<Integer>();
IntStream ints = integerList.stream()
.flatMapToInt(x -> IntStream.of(x) );
DoubleStream doubles = integerList.stream()
.flatMapToDouble(x -> DoubleStream.of(x) );
LongStream longs = integerList.stream()
.flatMapToLong(x -> LongStream.of(x) );



I have multiple problems with this explanation.
1.

The flatMap() method exists on primitive streams as well.


The example isn't calling .flatMap() or anything else on any primitive streams here, it is calling it on a normal Stream<Integer> which is just like any other Stream<Object>, no??

2.  

It works the same way as on a regular Stream except the method name is different.  


Regular .flatMap() on a regular Stream is described as follows earlier in the chapter:

The flatMap() method takes each element in the stream and makes any elements it contains top-level elements in a single stream.  This is helpful when you want to remove empty elements from a stream or you want to combine a stream of lists.



They then give this code sample which is consistent with my understanding of using flatMap() to "unpack lists":



While this code snippet compiled and ran for me:


It seems like a pointlessly complex way of doing this:


Which was what I was thinking a normal conversion from Stream<Integer> to IntStream would look like.

Now, they described it as working just like regular .flatMap() except for the name.  That seems to be true because this worked for me:


But that example isn't in the book, the one I gave at the top of the post is.

So, what's the deal with .flatMapToInt(), .flatMapToDouble() and .flatMapToLong() ?
The explanation and code in the book seems wrong to me.

 
Jesse Silverman
Bartender
Posts: 1064
33
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have found two previous questions about this (that I missed and didn't make it into the errata):

https://coderanch.com/t/735739/certification/Sybex-CSG-strange

and:

another one I just commented on...
https://coderanch.com/t/733819/certification/Sybex-Chapter-error

If I realized the other thread existed I would have just appended to it.
Our confusion stemmed from the same root.
 
Saloon Keeper
Posts: 4612
182
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The booktext IS somewhat confusing, but this is how I remember it:

IntStream -> flatMap -> IntStrseam
IntStream -> flatMapToObj -> Stream<Something>
Stream<Something> -> flatMap -> Stream<MaybeSomethingElse>
Stream<Something> -> flatMapToInt -> IntStream
 
Jesse Silverman
Bartender
Posts: 1064
33
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Piet, and I think that is right too (I am still learning the material).

Way more people are going to be reading the book than this thread, and while it is completely unreasonable to expect a certification preparation guide to teach you basic Java, I feel this is one of the difficult chapters where perhaps a majority are going to be learning the material for the first time.

It is so very, VERY rewarding, but not light reading or easy going.

It covers a LOT!

It really does feel like a whole new, generally better, way to program!

My mind is way out of my comfort zone, but a re-write of the section I complained about would do a lot to allay readers getting confused about an inherently slightly complex and likely new, and very important, part of migrating their brains to think in Streams.
 
Jesse Silverman
Bartender
Posts: 1064
33
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is it possible we could move this to the OCJP forum?

I didn't put Sybex 816/819 in the title originally because I was so confused upon first reading it that I wasn't sure if I was just confused or it was written in a confusing manner.

They never actually show a use of .flatMap() on a primitive stream type (it does NOT have a different name there, but the same one)

The problem is, I now see there are a LOT of options, including actually calling .flatMap() on a primitive stream type, and calling .flatMapToInt(), .flatMapToDouble(), .flatMapToLong() on an object Stream<T>, and some more...calling .mapToDouble(), .mapToLong(), .mapToObj() on an IntStream...etc., or if you just needed to convert and don't really need to map per se, DoubleStream asDoubleStream() and friends come to your rescue.

The number of options is a bit bewildering, and the box text makes it rather unclear about which of all these are in scope for the OCJP, one of the things I *do* definitely look to the Jeanne and Scott book for, rather than my new best friend, the Javadocs.

It looks like learning to use all of these various methods well would be a great idea if you are going to be using Stream as your go-to way of programming Modern Java, but those focused on preparing for the OCJP may get as overwhelmed as I did here, and wish to know which subset of these myriad method calls are fair game for the OCJP.

Anything actually in scope for the exam should probably appear in one of the various neat Summary Tables in the chapter, and also show at least one example in the text.

On the bright side, it appears that the ability to dynamically convert stream types via. intermediate operations is extremely rich and complete, trivially or whilst mapping or flatMapping at the same time which is a good thing, but it is much harder to know in this area which of all this is in scope for the exam.
 
Marshal
Posts: 73766
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:. . . My mind is way out of my comfort zone . . .

“Been there, done that, got the tee‑shirt.”
We all felt like that when we first wrote Streams code. Wait until you try things like collect(Collectors.groupingBy(Employee::getDepartment))!
 
Jesse Silverman
Bartender
Posts: 1064
33
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Jesse Silverman wrote:. . . My mind is way out of my comfort zone . . .

“Been there, done that, got the tee‑shirt.”
We all felt like that when we first wrote Streams code. Wait until you try things like collect(Collectors.groupingBy(Employee::getDepartment))!



Thanks Paul.  There's two levels here now:
1. You are a full Java Streams programmer.  Project Valhalla ain't here yet, and there are a million trivia points to know or get tripped up on in terms of Primitive versus Boxed Reference, a bunch of new ones relating to Streams.  There are many ways to cross-convert Stream types, simple Boxing, converting directly from one Primitive Stream Type to another, doing a (possibly non-trivial) mapping from some other object type to a primitive stream or vice versa, doing a flatMap from stream items (that are themselves convertible individually to a Stream) to a Stream of some other type, the whole box of 64 crayons.  "Reading the JavaDocs", which is a relatively recent Mantra for my Java work, they left out very few options!  You can do whatever conversions while doing anything else at the same time, or not.  This is VERY GOOD once you know it all, totally flexible, but completely overwhelming when first meeting and learning them.  I had a dream last night where I actually knew all of them, and was casually changing stream types as needed to solve my problems with Flair and Reckless Abandon.  I awoke to realize I am not there yet, but know very well other bodies of lore with Jeopardy-winner completeness, so if I keep at it I will get there.

2. You are someone seeking to pass the OCJP 819 exam.  Two of the hardest chapters, if you are using the Sybex 815/816/819 two volume set, are chapters 3 and 4 of the second book (not sure of the chapter numbers in the CSG) mostly because they cover a LOT of material that are likely to be mostly new to a high percentage of people who had been using Java casually for many years, partially because of a few places where the presentation could be a little clearer in that light.  You wish to ensure that you know the parts of Functional Interfaces, Collections, Generics and Streams (and Collectors) that are required to pass, much less ace, the 819.  That likely means a focus on the parts of these that are actually required and in scope for the exam, some students are better able to focus on that subset exclusively during preparation, but everyone sensible wants to be clear on what that subset is.  I don't know if the authors try to analyze where students who buy the books and start preparing and then give up are when they decide not to take the exam, I had seen very anecdotal evidence (including some here at the Ranch)  that a fair number of people Lost Hope in these two chapters.  I was in the midst of Chapter 4 when I got pulled away in other directions for several months (Python, C++, Unity, Android etc.) and came back a couple of months ago feeling I needed to review pre-reqs before I jumped back into chapters 3 and 4....

Campbell: I know that Collectors are so deep and powerfully functional that I consider them a whole topic unto themselves.  Venkat S. has a near-3-hour video lecture on JUST COLLECTORS, and his presentations move fast!  They seem to enable quite a high percentage of the sort of functionality one who knows SQL or Linq well can get out of them.  My near-term focus would be to know everything about them that is in scope for the 819, but a fuller knowledge seems to expand the scope of "What you can do with a Stream" to unimagined heights (or depths for the confused or bewildered)....so near term goal "What do I need to know about Collectors for the 819", longer term goal, how I can use them to accomplish things I never thought Streams would be powerful enough to do...
 
Campbell Ritchie
Marshal
Posts: 73766
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:. . . how I can use them [=Collectors] to accomplish things I never thought Streams would be powerful enough to do...

There are three stages to that:-
  • 1: Knowing that Streams can do XYZ at all.
  • 2: Knowing which book it is in, and better if you find the page.
  • 3: Knowing how to copy from the book implement your desired functionality.
  •  
    author & internet detective
    Posts: 40726
    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've made a note to revisit this for Java 17.
     
    Time flies like an arrow. Fruit flies like a banana. Steve flies like a tiny ad:
    the value of filler advertising in 2021
    https://coderanch.com/t/730886/filler-advertising
    reply
      Bookmark Topic Watch Topic
    • New Topic