• 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Junilu Lacar
  • Paul Clapham
  • Knute Snortum
Saloon Keepers:
  • Stephan van Hulst
  • Ron McLeod
  • Tim Moores
  • salvin francis
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Vijitha Kumara

Idioms to ease the shift from imperative to functional style  RSS feed

 
Sheriff
Posts: 13366
221
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi folks.

Based on the discussion here: https://coderanch.com/t/705283/java/beginners-familiar-Streams, I thought it might be useful to compile a list of idioms that contrast imperative style code with functional style code. Here's the first one that was discussed in the other thread:

Intent: Iterate over a range of integers

Imperative style:

Functional style:


Notes:
1. Assume int max = ...
2. See https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#range-int-int-

What other idiom pairs like the above come to mind?
 
Marshal
Posts: 63791
209
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . compile a list of idioms that contrast imperative style code with functional style code. . . .

This one is similar to your first example.

Imperative style:

Functional style:
[edit]Link to IntStream#rangeClosed() method.
 
Saloon Keeper
Posts: 9986
206
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator





 
Stephan van Hulst
Saloon Keeper
Posts: 9986
206
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A big part of becoming a wizard with streams is learning how downstream collectors work:

 
Stephan van Hulst
Saloon Keeper
Posts: 9986
206
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Very useful static imports to make your code nice and fluent:
 
Rancher
Posts: 3116
110
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What about avoiding nasty index juggling? For instance: to transpose a matrix: (for brevity, I left out the checks for matrix to be rectangular)

It is also fun to rotate a matrix over 90, 180 or 270 degrees.
 
Campbell Ritchie
Marshal
Posts: 63791
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As you will see here, you can test the individual code points of a String. The example in the old thre‍ad tested whether a “token” comprises only letters. You can get IntStreams from a CharSequence with its chars() or codePoints() method. Remember there is no such thing as a CharStream, so the chars are zero‑extended to ints.
Before (copied from Winston's post):-After:-The absence of a CharStream type means you have to do some jiggery‑pokery and turn it into a Stream<Character>. Character#valueOf() doesn't take an int as its parameter:-Had they written a CharStream interface, that code could have looked much more elegant. Maybe Oracle thought it was better to get away from the primitive char.
 
Stephan van Hulst
Saloon Keeper
Posts: 9986
206
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I avoid char like the plague. Get used to working with code points (and IntStream) if you need to manipulate elements of a string. It will save you a lot of pain when you suddenly need to move away from western languages.
 
Campbell Ritchie
Marshal
Posts: 63791
209
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There were four methods which I think were forgotten in the original Streams API:-
  • 1: Scanner#tokens()
  • 2: 2½: Scanner#findAll(), which is overloaded. Cay Horstmann complained about the absence of such Scanner methods here.
  • 3: A way to miss out leading values until a sentinel value is reached: Stream#dropWhile()
  • 4: Maybe the opposite of Stream#dropWhile(): a way to take elements until a sentinel value is reached: Stream#takeWhile()
  • Fortunately Java9 remedied all those four failings.

    BeforeAfterOrBeforeAfterBeware if sentinel and sentinel2 are the same::-Line 5 is only there as belt and braces. I think that without line 8, you will get the 0 passed to takeWhile(), and that will produce a 0‑length array. Also that I am working on a start inclusive end exclusive basis.
    Remember that a Scanner reading System.in always implicitly has a next token, so you must terminate the Stream with limit(), takeWhile() or similar.
     
    Bartender
    Posts: 20562
    120
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Stephan van Hulst wrote:I avoid char like the plague. Get used to working with code points (and IntStream) if you need to manipulate elements of a string. It will save you a lot of pain when you suddenly need to move away from western languages.





    Unless I am very mistaken, "char" is a Unicode character. Not the same thing as in C/C++ where "char" practically means thinly-disguised byte. So I fail to see where using char with non-western languages makes any difference.

    In fact, the pædant in me says that treating characters as integers is the more questionable practice.
     
    Sheriff
    Posts: 24288
    55
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Tim Holloway wrote:

    Stephan van Hulst wrote:I avoid char like the plague. Get used to working with code points (and IntStream) if you need to manipulate elements of a string. It will save you a lot of pain when you suddenly need to move away from western languages.





    Unless I am very mistaken, "char" is a Unicode character. Not the same thing as in C/C++ where "char" practically means thinly-disguised byte.



    In fact "char" is a Unicode character in the Basic Multilingual Plane. This plane represents the first 65,536 characters of the Unicode character set and covers essentially all characters used by any living language on Earth. Other planes (for which you need to distinguish code points from characters) cover such things as Linear B, Deseret, Manichaean, Pau Cin Hau, and a whole boatload of scripts which I'd never heard of. (Also Chess Symbols but that's a different thread.) So unless you're really into esoteric scripts you can get away with just considering a String to be a sequence of chars.

    However using code points instead of chars isn't going to be a problem for your code, since the two approaches are going to work identically unless you stray from the BMP. So I wouldn't reject Stephan's advice, I would just suggest that it's unnecessary except for a few specialist applications.
     
    Saloon Keeper
    Posts: 2188
    92
    Eclipse IDE Google Web Toolkit Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Null check avoidance
    old:
    new:
    Setting default value using optional
    old:
    new:
    Combining Data
    old:
    new:
     
    Greenhorn
    Posts: 5
    • Likes 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This thread is great. I just discovered Java Streams last month and my brain was baffled and amazed with the ease and flexibility of functional programming. It set me off on an appetite for functional programming knowledge that has completely changed the way I write java programs.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 9986
    206
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Tim Holloway wrote:Unless I am very mistaken, "char" is a Unicode character. Not the same thing as in C/C++ where "char" practically means thinly-disguised byte. So I fail to see where using char with non-western languages makes any difference.


    Sorry, I meant to say non-western scripts.

    In fact, the pædant in me says that treating characters as integers is the more questionable practice.


    Questionable on part of the Java developers. The fact of the matter is that ints are used to represent code points, and for future proof applications it's better to use code points than chars. If Java had a CodePoint class or primitive, I would have loved to use that.

    Paul Clapham wrote:Other planes (for which you need to distinguish code points from characters) cover such things as Linear B, Deseret, Manichaean, Pau Cin Hau, and a whole boatload of scripts which I'd never heard of. (Also Chess Symbols but that's a different thread.) So unless you're really into esoteric scripts you can get away with just considering a String to be a sequence of chars.


    Except that there are already a myriad of web applications that broke because they didn't take modern uses into account, such as emoticons. And using code points isn't that much more difficult than using chars in practice, because you can use character literals just fine.
     
    Campbell Ritchie
    Marshal
    Posts: 63791
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    KP, welcome to the Ranch
     
    Paul Clapham
    Sheriff
    Posts: 24288
    55
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Stephan van Hulst wrote:Except that there are already a myriad of web applications that broke because they didn't take modern uses into account, such as emoticons. And using code points isn't that much more difficult than using chars in practice, because you can use character literals just fine.



    Yeah, true enough. But I'm pretty sure that there a lot of Java programmers out there who haven't caught up yet with the distinction between chars and code points (which that distinction entered Java in 2004), so it's worth mentioning it from time to time.
     
    Campbell Ritchie
    Marshal
    Posts: 63791
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    See this thread.
    Before:-You can calculate the minimum similarly, but that technique will fall over horribly if you pass it a 0‑length array. Also I am pretending not to notice whether I am doing integer division anywhere.
    After:-You can shorten that to
     
    Piet Souris
    Rancher
    Posts: 3116
    110
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:You can shorten that to


    small correction:

    Problem is that that Int/DoublesummaryStatistics doesn't contain the variance and standard deviation. However, it is a good exercise (and easy as well) to write a more powerfull Statistics.
     
    Campbell Ritchie
    Marshal
    Posts: 63791
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thank you for the correction. I don't think any of those statistics objects contains σ etc. Standard deviation is obviously an advanced topic
     
    Marshal
    Posts: 6634
    443
    BSD Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I don't think I ever saw .parallelStream() on these forums.

    What's the story about that?
     
    Piet Souris
    Rancher
    Posts: 3116
    110
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I hink becaue parallel streams are frightening. Can you always easily see that parallelism always works? For instance, to take the average of a stream, can you split the stream into parts and somehow calculate the mean of the parts and combine these into the correct overall mean? I couldn't find the requirements for doing things parallel, but to my surprise the Int/DoubleSummaryStatistics worked flawlessly in parallel. Will have a look at that tomorrow.
     
    Campbell Ritchie
    Marshal
    Posts: 63791
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Piet Souris wrote:. . . Can you always easily see that parallelism always works?

    No, you can't; you have to trust Oracle that they did the work of creating Streams correctly.

    For instance, to take the average of a stream, can you split the stream into parts and somehow calculate the mean of the parts and combine these into the correct overall mean? . . . .

    No; you would calculate separate sums, maxima, minima etc., and combine them when the separate parallel Streams merge together.
     
    Piet Souris
    Rancher
    Posts: 3116
    110
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:

    Piet Souris wrote:. . . Can you always easily see that parallelism always works?

    No, you can't; you have to trust Oracle that they did the work of creating Streams correctly.

    For instance, to take the average of a stream, can you split the stream into parts and somehow calculate the mean of the parts and combine these into the correct overall mean? . . . .

    No; you would calculate separate sums, maxima, minima etc., and combine them when the separate parallel Streams merge together.


    Indeed, and like you write, it takes a lot of faith in Oracle!
     
    salvin francis
    Saloon Keeper
    Posts: 2188
    92
    Eclipse IDE Google Web Toolkit Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Does it have a (huge) performance gain ?
    I think I tried something a while ago and I didn't see much difference in performance, but YMMV
     
    Campbell Ritchie
    Marshal
    Posts: 63791
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The performance varies; on my previous laptop there wass a big improvement when I parallelised things, but there doesn't see to be that much difference on my current machine. There is a chapter about performance in Maurice Naftalin's book.
     
    Liutauras Vilda
    Marshal
    Posts: 6634
    443
    BSD Linux Mac OS X VI Editor
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I picked up the book "Functional Programming in Java" by Dr. Venkat Subramaniam, there is a chapter "Taking a Leap to Prallelize", p. 143.

    So what he (author of the book) mentions there, that to parallelize execution and make it concurrent, there is a cost for that, and in most cases if the collection is relatively small or/and operation boundaries are only within the collection items, paralellising makes even slower, as between the operations really there isn't any possible "bottlenecks" which could make operation wait until other finishes. I ran some of the tests, and indeed, test results proved that.

    Tried with some pointless program:

    However, when let's say you streaming collection and based on the given element you need to i.e.: map its value to something let's say based on retrieved information from some web service, this is where the parallelism very likely can outperform singular stream. For that I still need to come up with some test to see in real.

    So need to be careful with parallel streams and analyze it well to understand whether it can make execution time better or not.
     
    Our first order of business must be this tiny ad:
    global solutions you can do at home or in your backyard
    https://www.kickstarter.com/projects/paulwheaton/better-world-boo
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!