1. Overview
In this tutorial, We'll learn about java 8 Supplier Functional Interface.Supplier is part of package java.util.function. This is introduced in Java 8 as part of Function programming.
Api Reference
Supplier Functional Interface has only one Abstract method.
T get()
Where T - the type of results supplied by this supplier
This method is called as Functional Method.
Suppliers are very useful when we do not need to supply any value but need to return a value at the same time.
Now, We will see how to use Supplier to get the randome number using Math class.
Math class a static method random() that returns a random value between 0.0 and 1.0.
In previous article, We have discussed Lambda Expressions. We must have an idea about Lambda to work with Functional Interface.
This method is called as Functional Method.
Supplier does not take any argument but returns a value always. Because of this named as Supplier as supplies everytime something when we call get() method.
Suppliers are very useful when we do not need to supply any value but need to return a value at the same time.
2. Example to generate random number using Supplier
Now, We will see how to use Supplier to get the randome number using Math class.
Math class a static method random() that returns a random value between 0.0 and 1.0.
In previous article, We have discussed Lambda Expressions. We must have an idea about Lambda to work with Functional Interface.
SupplierrandomSupplier = () -> Math.random();
Just take a look at the above functional code that Supplier returns Double value.
How to know the type of the value.
This is very simple to find. Just see what type is retuned by lambda exp, that value we shuould mention as part of the Supplier declaration.
Next, We should call the get() method.
How to know the type of the value.
This is very simple to find. Just see what type is retuned by lambda exp, that value we shuould mention as part of the Supplier declaration.
Next, We should call the get() method.
System.out.println("Random value 1 "+randomSupplier.get());
Once get() method is invoked then immediately lambda will be executed automatically and excutes Math.random() method which returns a random value.
See the below output.
Output:
Random value 1 0.9235006477846478
Note: get() method can be called multiple times on supplier.
The below code is completely valid.
System.out.println("Random value 2 "+randomSupplier.get()); System.out.println("Random value 3 "+randomSupplier.get()); System.out.println("Random value 4 "+randomSupplier.get()); System.out.println("Random value 5 "+randomSupplier.get());
Produces the below output.
Random value 2 0.26474106955613286 Random value 3 0.2613837445870235 Random value 4 0.41373430220646323 Random value 5 0.4281632448845335
3. Supplier Example to fix "stream has already been operated upon or closed"
Observe the below code that works fine.Listfruits = Arrays.asList("Mango", "Jack Fruit", "Water Melon", "Apple"); Stream stream = fruits.stream(); Optional anyFruitName = stream.findAny(); System.out.println(anyFruitName.get());
Output:
Apple
But, If we perform any operation stream again then we will get runtime exception.
Exception:
Here, the problem is performing the operations on stream which is already closed.
To fix this issue, we need to recreate a new Stream object.
See the complete article on "java.lang.IllegalStateException: stream has already been operated upon or closed"
This problem can be solved using Supplier as below instead of repeating the code twice to create the Stream object from fruits list.
Here, It calls the no-arg constructor.
If we want to call the argument constructor then there is a limitation for Supplier.
In this article, We've studied about Supplier Functional Intetface added to java 8. Supplier has only one get() abstract method and should be used with Lambda for best practicies.
Seen the example program to get the random number and fix to a common error working with streams "java.lang.IllegalStateException: stream has already been operated upon or closed"
And also seen a note on Method Reference.
All the code shown in this post is over GitHub.
OptionalfirstFruitName = stream.findFirst();
Exception:
java.lang.IllegalStateException: stream has already been operated upon or closed at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229) at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543) at com.java.w3schools.blog.java8.functional.SupplierStreamFix.main(SupplierStreamFix.java:17)
Here, the problem is performing the operations on stream which is already closed.
To fix this issue, we need to recreate a new Stream object.
See the complete article on "java.lang.IllegalStateException: stream has already been operated upon or closed"
This problem can be solved using Supplier as below instead of repeating the code twice to create the Stream object from fruits list.
Supplier> streamSupplier = () -> fruits.stream(); Stream anyStream = streamSupplier.get(); System.out.println("anyStream " + anyStream.findAny().get()); Stream firstStream = streamSupplier.get(); System.out.println("firstStream : " + firstStream.findAny().get());
4. Method Reference
Suppliers can be used with Method Reference.//Mehtod Reference SuppliermethodRef = String::new;
If we want to call the argument constructor then there is a limitation for Supplier.
Note: That's just a limitation of the method reference syntax that you can't pass in any of the arguments. It's just how the syntax works.
5. Conclusion
In this article, We've studied about Supplier Functional Intetface added to java 8. Supplier has only one get() abstract method and should be used with Lambda for best practicies.
Seen the example program to get the random number and fix to a common error working with streams "java.lang.IllegalStateException: stream has already been operated upon or closed"
And also seen a note on Method Reference.
All the code shown in this post is over GitHub.
No comments:
Post a Comment
Please do not add any spam links in the comments section.