Win a copy of Machine Learning with R: Expert techniques for predictive modeling this week in the Artificial Intelligence and Machine Learning forum!
  • 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
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Ganesh Patekar

Java functional programming program to find odd numbers in a arrayList?

 
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have created a java functional programming program to find odd numbers in an arrayList?
Is this functional programming program done the right way?



Thanks
 
Saloon Keeper
Posts: 10675
228
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No.

The point of functional programming is that you pass functions to higher order functions that apply your function in a way that is specific to the higher order function.

Instead, you have just created a function and called it directly. It's just a messy and roundabout version of a direct method call.

Additionally, you've created a functional interface that seems to have only one use. The point of a functional interface is that it's generic enough that it can be uses in a wide range of scenarios.

It appears that for each integer in a source of integers, you want to print whether the integer is even (despite the name of your function implying the opposite). You can break that up in two higher order operations: a map operation and a for-each operation. First you map each integer to an object you want to print, and then for-each object, you print it.

It's also possible to create the source of integers in a more functional way. This is how it could look:

As you can see in this example, the IntParity constructor and the println() method are treated as function objects and passed to the higher order functions mapToObj() and forEachOrdered().
 
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:Is this functional programming program done the right way?


No, that's not quite what FP-style code looks like in Java.

This is more along the lines of what "functional programming in Java" means:

Copy and paste that into JShell and try it out.

You can even shorten that down to just one statement:

The semantics of your code is also backwards from the norm. Anyone who is familiar with FP-style programming in Java will likely get confused by this (as I was at first):

As you can see in my example, the filter() method says "I want only even-numbered values". Your code appears to want to say "I don't want odd numbered values". It's basically the same logic said in a different way but yours has a nuance that carries a cognitive load similar to a double negative. You can make it more "standard" and remove the extra cognitive load by changing the name from filterOddNumbersFunc to isEven.

Functional programming is characterized by code that is declarative rather than imperative and is stateless rather than stateful. There are probably more differences but I'll leave the further digging work to you. Good luck.
 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is imperative style programming:

This is declarative:

See the difference? The explicit control structure (the for-loop) in your code gave it away as being imperative-style. In functional-style programming, iterative control structures are abstracted away by expressive functions like forEach() that declare the intent but hide the nitty-gritty implementation details.

The forEach() function is also an example of a higher-order function that Stephan mentioned in his reply. It takes a method reference (System.out::println), which is essentially another function, as its parameter. Likewise with filter() which takes a Predicate like isEven or a lambda expression like n -> n % 2 == 0.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I should have clearly used the filter method for this kind of operation. What about the cases where we are doing an operation for which no direct method is available.?
 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:What about the cases where we are doing an operation for which no direct method is available.?


Like what, for example? Give a concrete example of what you mean.
 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think you'll quickly find such a scenario. The Stream class contains most of the fundamental higher order functions: of, iterate, concat, skip, limit, filter, dropWhile, takeWhile, map, flatMap and reduce/collect.

The most important higher order function that is missing from the standard API is zipWith. Usually when you want to zip two streams in Java, you have to do it procedurally using two iterators.
 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also note that functional programming is more than just calling higher order functions and passing function objects. There are important functional features that Java doesn't support, including but not limited to lazy function evaluation, partial function application, pattern matching and guards.
 
Sheriff
Posts: 6269
167
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:IThe most important higher order function that is missing from the standard API is zipWith. Usually when you want to zip two streams in Java, you have to do it procedurally using two iterators.


Correct me as I'm guessing here.  The difference between zipping and concatenating is that zipping takes one element from the first stream, then one from the second stream, and so forth?
 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:Correct me as I'm guessing here.  The difference between zipping and concatenating is that zipping takes one element from the first stream, then one from the second stream, and so forth?


Yup, that's about the gist of it. W3Schools has a nice example for Python: https://www.w3schools.com/python/ref_func_zip.asp - you'll see that you end up with a list of tuples.
 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, zipping is pairing up each element from one stream with an element from the other stream and then applying a binary function to each pair to yield a result stream.
 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:No, zipping is pairing up each element from one stream with an element from the other stream and then applying a binary function to each pair to yield a result stream.


Except for the part that I've emphasized, I thought that's kind of what Knute said, isn't it?
 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I interpreted Knute's description as zip yielding a flat stream of alternating elements.
 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:I interpreted Knute's description as zip yielding a flat stream of alternating elements.


I thought that might have been it. I was just about to mention flatMap, too.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are there no use case where one would create a functional interface and them apply the function like I had tried to apply in my example?
 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To be very blunt, your example is not a good example.

As Stephan said: "Instead, you have just created a function and called it directly. It's just a messy and roundabout version of a direct method call."
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
filter()  taking a lambda expression like n -> n % 2 == 0  is a case of inbuilt method (filter).   Are there any use cases where we use our own custom functional interfaces.e. g The example which I had given is wrong but it has our own custom interface.
 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:Are there no use case where one would create a functional interface and them apply the function like I had tried to apply in my example?


There's one scenario I can think of where you would create a function object and call it inside the same method without passing it to a higher order function. Imagine you have an action that needs to be performed on a resource that needs to be closed as quickly as possible. Which action to perform depends on some condition that takes a long time to evaluate. Here's one approach:

The problem with this approach is that the resource is occupied all the time the condition is being evaluated. To improve the situation, we want to evaluate the condition before we claim the resource:

That's just a lot of ugly repetitive code. To get the best of both worlds, we determine the action to perform on the resource separately from the try-with-resources statement, so we only have to write the code to claim the resource once:

Now we have a concise piece of code that doesn't repeat itself, and also closes the resources as quickly as it can. This scenario doesn't really happen a lot though, so you will rarely find an opportunity to write such code.

Monica Shiralkar wrote:Are there any use cases where we use our own custom functional interfaces.e. g The example which I had given is wrong but it has our own custom interface.


Sure, usually when you write a general purpose service that handles a common problem and lets the client deal with the specifics. For example, back when I was still writing a lot of board- and card-games in Java, I would eventually add the ability to play them over a network with friends. I found that I was writing the same code to handle sockets over and over again, so I ended up writing a generic Server class that accepted incoming connections, and delegated them to socket handlers that a client could provide through a functional interface.

Here's the constructor:

The SocketHandler type was a functional interface that I had written myself:

Now, it was actually a little bit more impressive than that, because it contained detailed documentation telling what circumstances a handler could expect and what was required of a handler, but the point is that there was a functional interface that was generic enough that it could be used in a wide range of applications.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, why doest it have to be generic that can be widely used?
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What would be wrong if it is not generic?
 
Bartender
Posts: 3519
150
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I once had to define a TriPredicate. In my special case, I could have defined:

and I can implement that for the very special case of having the three parameters being a String, an int and a char.
But I did it like this:

It is widely applicable, and the text is even shorter! So, why not making it generic?
 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Generics is a whole different matter altogether. In my previous reply, whenever I used the word generic I really meant "widely usable", not "using type variables".

Recognizing when you can use functional interfaces and recognizing when you can use generics are separate concerns. A functional interface often uses generic type parameters, but it's not necessary, as seen in my SocketHandler interface. Piet gave a good example of when you WOULD use generics.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Monica Shiralkar wrote:What about the cases where we are doing an operation for which no direct method is available.?


Like what, for example? Give a concrete example of what you mean.



I am talking about the below kind of case and converting this code to Java Functional lambda expression:


 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, I don't understand what you're trying to get at. You can either call that directly or use a method reference like WhateverClassThatsIn::isArmstrong which can be assigned to any compatible functional interface.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But if I call it directly then then how will it be the case of using lambda expression.
 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I get a sense that you think lambda expressions are the key to FP in Java. Lambda expressions are just a mechanism for supporting functional style programming. Method references, functional interfaces and streams are other mechanisms available to you. Use the right tool for each context. Learn which tool is the appropriate one for whatever context you have. Don't think that you have to use a lambda for everything FP in Java. Sometimes it's appropriate, sometimes it isn't. It just depends.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. Is lambda expression to be avoided in this example (determine whether a number is Armstrong number)?

 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think finding the answer to that question yourself would be the first step to you learning when it's appropriate to use lambdas. My rule of thumb is that if a tool makes a task easier to do, it's appropriate for that task. If not, well...

So, what do you think?

There comes a time in one's learning journey that you must stop asking questions of others and figure things out for yourself. I think this is such a time.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks.

I had read that lambdas expressions in Java help  to achieve the same result in less lines of code (and some call it more readable too).

We need to understand that we cannot use it anywhere and everywhere.

If I use lambda in the example that I had written in above post (find whether the number is Armstrong or not), it would not reduce the amount of code we have to write to accomplish this.


However, if I change the above example to instead take an arrayList of numbers  and print for each number if  it is Armstrong or not, then Lambda expression surely will help us achieve this in lesser code because without Lambda expression, we will have to iterate each element and check whether it is Armstrong and print while if we use lambda expression then we can use forEach (x-> checkIfArmstrongAndPrintIt(x))    

Is this correct?

 
Marshal
Posts: 65821
250
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Monica Shiralkar wrote: . . . Is this correct?

Have you tried it? What does the code look like with a λ and what does it look like in imperative coding? Have you compared the two? Don't expect to learn anythi8ng without your putting any effort into it.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried these and to understand I also went back to the most basic program of Java Lambda which concatenates Hello with the name and prints



Greetings without lambda




In the above two programs although I understand how lambda expressions can be applied, it does not show benefit of using lambda expression in this case it although this is a widely used example as a hello world of lambda. The amount of code is not reduced.

I also modified the programs to iterate a list of names and print after concatenating Hello with every name.




Greetings for all names in a list without lambda



In the above programs too although it shows how lambda expressions can be applied, it does not show benefit of using lambda expression in this case too.The amount of code is not reduced.


Are these examples not at all suitable to show the benefit of using lambda(instead of calling directly)? If so how can I modify these to see the benefit of lambda?
 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's mostly because these examples use the forEach method, and forEach is not functional. forEach is procedural, even if it accepts a function object.

The expressiveness of higher order functions becomes apparent when you use the classical operators, like map, filter, and reduce/collect. Compare the following two code snippets:

Imperative:

Declarative:

As you can see, the difference is code length is not that great. You need to let go of this idea that shorter code is the main advantage of functional programming, or even an advantage at all. The advantage of functional programming is that you tell the computer WHAT you want it to compute and not HOW you want it to compute it.

In the first snippet, we first had to tell the machine to create an ArrayList. We also had to tell it to call the List.add() method to add cities to the list. In the second snippet, we just told it that we are only interested in African countries, we want their capital cities, and we want a list of them. We don't care where the list comes from or how the cities are added to it.

Note also that I haven't used any lambda expressions. I THINK that whenever you say lambdas, you really mean functional operators. Lambda's are just a convenient way to to create a single use function when you don't want to make a separate method to call instead.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. The last line is a good definition of lambda expression.   Lambda's are just a convenient way to to create a single use function when you don't want to make a separate method to call instead. Also, the benifit of using Lambda should be that it should help on doing functional programming that is for the benifit of telling  WHAT you want it to compute and not HOW you want it to compute it.

In't this we want to always do?( tell the computer WHAT you want it to compute and not HOW you want it to compute it). Above in the thread it was said that we should use lambda only where it is suitable  and it is not the  only way to do Functional programming.  It is correct and that's about lambda's. Regarding functional programming when should we use functional  programming and when should be avoid it because "tell the computer WHAT you want it to compute and not HOW you want to compute is"  is something we would always want to do.
 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It depends on the situation. Some problems are easier to solve using procedural programming, usually when the state of the application has to vary with time. That's why functional languages like Haskell have something called "do notation", which really is procedural programming, no matter how much functional programming aficionados insist that it's not.

The ability to see which approach is appropriate comes with experience. You only get that by practicing and have your work peer reviewed.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think among the examples which I posted above to append hello before each name in a list and print it, in the second example (without using lambda)  it iterates the list and for each element does that which means telling how we want to do it whereas for the first example it direct tells using arrow sign what we want to do instead of how we want to do it. Is that correct?
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can the  below Greetings program using Java lambda be changed such that the name of the Functional interface is not at all required?








 
Stephan van Hulst
Saloon Keeper
Posts: 10675
228
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, you can use a different functional interface, such as Function<String, String>, but other than that not really. Java is a statically typed language, and you must specify the types of parameters explicitly, even if the parameter holds a function.

This is not any different in languages like Scala or Haskell, except there the type is specified by typing something similar to String -> String instead of Function<String, String>.

I strongly recommend that if you want to learn more about functional programming, you stop asking questions and start writing programs in a language that doesn't leave you any choice, such as Haskell. You are not doing yourself a favor by constantly comparing a procedural programming style to a functional programming style.

I know you're also learning Scala and C#, and I think you've shot yourself in the foot trying to learn multiple languages before you've mastered one. Finish your education in Java and focus on the old procedural style. If you feel confident, Google LearnYouAHaskellForGreatGood. It's one of the best written tutorials I've ever come across.
 
Monica Shiralkar
Ranch Hand
Posts: 1258
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. I have been working mainly on Java. I was put in a project which requires C#,  so I am learning and implementing it. Scala, I am learning for a Spark project in our team.
 
Junilu Lacar
Marshal
Posts: 14060
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@MS, I agree with just about everything Stephan has advised you except for one small but important detail, which I'm sure was unintentional on Stephan's part: Java is an object-oriented language, not a procedural language, so please learn how to write proper object-oriented programs in Java. Procedural Java programs are just about the worst kind of code I've ever had the misfortune to have to work with. I wouldn't wish that on anyone so please try not to add to that hellspawn if you can.

What I think Stephan meant to say was to stop comparing imperative against functional style programming. That is to say, the style most people learn when programming Java is imperative style (using for-loops, if statements, and other imperative-style flow control structures). Once you've mastered that style and have a solid understanding of what its advantages and disadvantages are, then learn functional style programming where flow control statements for iterations and decisions get abstracted away as the code becomes more declarative.
 
Wanna see my flashlight? How about this tiny ad?
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!