Java8: Oogways more advice on Optional.

Oogway's previous talk clears the confusions about Why Optional is added on java8? But PO is a Dragon warrior he is the finest Java warrior so he wants more, He wants to know when is the right time to use Optional. What are the best practices so he again went to Oogways and I am very lucky PO called me to take the note of the talk.
Here is the Conversation.

PO: Master Oogway, I completely understood why we use Optional, the crux of the Optional is -- it gives the caller a hint that output may not be available so, design your code accordingly. So it is a Conceptual improvement which force caller to tackle maybe scenario and the outcome -- less null pointer exception. But How to use it efficiently.

Oogways: PO, Listen carefully Optional is created to check a return value is present or not, So it is the one and the only purpose you should use Optional nothing else. Optional act as a container it wraps the return value and then applies different functions on it to determine value is present or not in an advance if the value is present it can take necessary functions on it in a functional way. but whatever the case Optional must be used with method return type. Use Optional<T> as a Composition or pass it is an input is a very lame idea and should be avoided.

PO: What is the problem to pass Optional as an input suppose I have a program to search a name so if I pass the name as Optional<String> developer don't have to do the null check.
see the below program.

package com.example.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class OptionalTest {

private static List<String>nameList = new ArrayList<String>();

static {
nameList.add("shamik");
nameList.add("samir");
nameList.add("swastika");
}

Optional<String> findName(Optional<String> name){
return name.isPresent()?Optional.of(nameList.get(nameList.indexOf(name.get().toLowerCase()))):Optional.empty();
}

public static void main(String[] args) {
OptionalTest optionalTest = new OptionalTest();
Optional<String> searchedNameOptional = optionalTest.findName(Optional.of("Shamik"));
Optional<String> searchedNameOptionalSecond  = optionalTest.findName(Optional.ofNullable(null));
searchedNameOptional.ifPresent(System.out::println);
searchedNameOptionalSecond.ifPresent(System.out::println);
}

}

Here, I create a method called findName which takes an Optional<String >, So that developer can check if the value is present or not if present same returns an Otional<String> else returns an Empty optional, So no null check involved and passing Optional caller signal to the developer that passing parameter may be present or absent so deal accordingly. Nice way to tackle input parameters. Master then why you are telling passing an Optional in the input is a bad idea?

Oogways: PO, There is a subtle conceptual error in your thinking,
You are right Optional is used for signaling value can be present or absent, But think about who signaling to whom, here caller signaling to the author of the code, The author is the creator of the code, author is very sure about nature of method input and returns value. As he wrote the method. So here signalling is meaningless, if caller only pass the name , the author knows value may be null as default value of String is null, so he can take care of it , So here use of Optional is redundant-- here Optional means Developer of the code reminds himself passing parameter may be present or absent-- just nonsense. Optional works fine for the client of the method as the client does not know about what the method is doing inside he only knows by call findName I can get an Optional<String >, So this method may give a blank result so I need to tackle it. But the reverse perspective is just absurd. There is no need to signal developer as he controls the implementation he knows what to do with inputs, so in this case null check is better than Optional, Another thing is -- by passing an Optional you create a wrapper on a value so it takes more memory space an unnecessary complex the code violation of KISS(keep it simple stupid), Also caller has to create Optional container which is break of encapsulation. So the best way to represent your code is like that

package com.example.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class OptionalTest {

private static List<String>nameList = new ArrayList<String>();

static {
nameList.add("shamik");
nameList.add("samir");
nameList.add("swastika");
}

Optional<String> findName(String name){
return name !=null?Optional.of(nameList.get(nameList.indexOf(name.toLowerCase()))):Optional.empty();
}




public static void main(String[] args) {
OptionalTest optionalTest = new OptionalTest();
Optional<String> searchedNameOptional = optionalTest.findName("Shamik");
Optional<String> searchedNameOptionalSecond  = optionalTest.findName(null);
searchedNameOptional.ifPresent(System.out::println);
searchedNameOptionalSecond.ifPresent(System.out::println);
}

}

By this, Developer put the null check, Always remember Optional is not an option for replace null or apply some functional fancy methods apply on value like (filter/map) etc. The Optional is for signaling a value is present or not. So don't use it in composition or input variables for just sake for using Optional.
PO: Now, I understood the same master, Now please tell some of the operation we can do using Optional?

Oogways: Yes PO Now we are in a position where we can use some of the Optional 's utility methods.

orElse and orElseGet: Sometimes, you are sure about what would be the default value if a value is not present in that case you can use orElse on the Optional. Suppose if the name is not found we show "NA" as default value, in that case, we can change the findName method as following

package com.example.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class OptionalTest {

private static List<String>nameList = new ArrayList<String>();

static {
nameList.add("shamik");
nameList.add("samir");
nameList.add("swastika");
}



public String findName(String name){
return Optional.ofNullable(name).map(val->nameList.get(nameList.indexOf(val.toLowerCase()))).orElse("NA");

}





public static void main(String[] args) {
OptionalTest optionalTest = new OptionalTest();
String blankName = optionalTest.findName(null);
String name = optionalTest.findName("Shamik");
System.out.println("Name is :: " + blankName);
System.out.println("Name is :: " + name);

}

}

Here I use a map function which will check the name is in name List or not if it is not found it will return "NA" as in orElse I provide the default value as "NA".
Now, If the default value fetched from Database or from a locale based properties file then we need to write a separate method which returns the default value, in that case, we can use that separate method as a reference and pass a supplier interface in the orElseGet method. See the following example.

isPresent and ifPresent : Optional has two utility functions called isPresent and ifPresent, former returns true if a value present later takes a callback function which will apply on the value if the value is present. So when you see a code block like following

if(optional.isPresent()){
 doSomething();
}

replace the same with ifPresent

optional.ifPresent(val->doSomething())

see the below Example,

package com.example.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class OptionalTest {

private static List<String>nameList = new ArrayList<String>();

static {
nameList.add("shamik");
nameList.add("samir");
nameList.add("swastika");
}

Optional<String> findName(Optional<String> name){
return name.isPresent()?Optional.of(nameList.get(nameList.indexOf(name.get().toLowerCase()))):Optional.empty();
}

public static void main(String[] args) {
OptionalTest optionalTest = new OptionalTest();
Optional<String> searchedNameOptional = optionalTest.findName(Optional.of("Shamik"));
if(searchedNameOptional.isPresent()) {
System.out.println(searchedNameOptional.get());
}
searchedNameOptional.ifPresent(System.out::println);

}

}
Here, I replace isPresent with ifPresent.

flatMap: The flatmap function works same as map function, i.e change one data structure to another data structure but if the return  data structure holds an Optional it does not create a nested Optional Structure Optional<Optional<T>> it  just returns only Optiona<T>
see the example

package com.example.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class OptionalTest {

public void flatMapTest(String name) {
Optional<String> retName = Optional.of(name).flatMap(val->Optional.of(val));
System.out.println(retName);
}


public static void main(String[] args) {
OptionalTest optionalTest = new OptionalTest();
optionalTest.flatMapTest("Shamik");
}

}

in FlatMap fuction I delibaretly return Optional.of(val) and as flatMap returns Otional<T> it should be then Optional<Optional<String>> but it returns only
Optional<String> if we use map function we got Optional<Optional<String>>

filter: we can use filter function on Optional so we can filter the value based on some criteria

package com.example.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class OptionalTest {

private static List<String>nameList = new ArrayList<String>();

static {
nameList.add("shamik");
nameList.add("samir");
nameList.add("swastika");
}

Optional<String> findName(Optional<String> name){
return name.isPresent()?Optional.of(nameList.get(nameList.indexOf(name.get().toLowerCase()))):Optional.empty();
}


public static void main(String[] args) {
OptionalTest optionalTest = new OptionalTest();
Optional<String> searchedNameOptional = optionalTest.findName(Optional.of("Shamik"));
searchedNameOptional.filter(val->val.contains("am")).ifPresent(System.out::println);

}

}



PO: Master I learned all the important functions is anything still left to know about Optional?

OogWays: Yes, PO we have covered 90% but one more thing is still pending why Optional is not Serializable, I will give you the answer but I want you to think about it. Tomorrow I will give the answer if you are not able to answer it.

PO: Ok Master.

Java8: Oogways Advice on Optional

While PO reading Java 8 Optional he has few question in mind and can not understand why Optional added in Java, How it saves us from the almighty villain null pointer Exception. So he goes to master Shifu, But the Irony is Shifu does not sure about How it will save Java users from the null pointer, but it is oogways foretold so they go to Oogways for advice on Optional.
I was there when the conversation happened, I will try to depict the conversation.
PO : Master oogways, I am really confused why Optional added in Java, I can't see any benefits , and I am bit skeptical how it saves from Nullpointer exception as it is nothing but a Container/Wrapper Object which held a reference to another Object, So the reference can be null and itself Optional wrapper class can be null, so I am confused what is the use case.
Oogway: From the birth of java the greatest sin is, The invention of null, Java tries to represent something absent as a null, but absent does not mean null it means not present. Java is a strong type language but null is such a value which can be assigned to any type, so it acts as a loose type variable, act as default value of reference, It is not blessing but a curse,
Every time we don't know what would be the returned Object, developers returns a null, and caller, unfortunately, bears the load of the null check for return value unless null pointer exception blows up the flow.
Let see a small example,

package com.example.optional;

import java.util.ArrayList;
import java.util.List;

public class OptionalTest {
private static List<String> nameList = new ArrayList<String>();
static{
nameList.add("Shamik");
nameList.add("Samir");
nameList.add("Swastika");
}

public String findName(String nameToFind){
return nameList.contains(nameToFind)?nameList.get(nameList.indexOf(nameToFind)):null;
}

public static void main(String[] args) {
OptionalTest test = new OptionalTest();
String searchedName = test.findName("Mayukh");
System.out.println(" Hi , " + searchedName.toUpperCase());
}


}
Here, The API developer exposes a method called findName, and silently return a null if the name is not found.  The caller of the API trust the API developer and called the method with an arbitrary name and try to print it in Uppercase. But it blows the caller's code with null pointer exception.
Whose fault is it Callers or API developer?

API Developers Perspective: When caller gives a name and that name is not found in nameList what should I do? return a blank string or return a String "NA" but if the caller says that they don't want "NA" or blank String, or One caller OK with the blank or "NA" String  and Other wants to handle the scenario by itself, so  as a developer when I am not sure what to return I always returns null. Yes, I am a good developer I can handle all the boundary cases.
Callers Perspective: findName is an API method I only command it to give me a search result "Tell Don't Ask", It is API method responsibility to handle boundary cases or cases if the searchable name is not found, It should give me a dummy implementation if the searchable name not found, like "NA". So I do not bother to check the return value, It is not my responsibility, so he skips the null check and programs blown up.

Really who's fault it is API developer or Caller?
Caller and Developer are right in their perspective, the confusion grows because API developer can't signal the caller, The return value may be present or absent. Null means no reference !!! (But How caller will  Understand current retuned reference not point to any Object instance?), so always it is caller responsibility to do a null check even if the value is present. null is not so expressive, to indicate caller a value is present or absent as it can be easily assigned to return value silently. So Optional step in here it tries to say value may be present or may be absent so caller it is your duty to check value is present or absent whereas null returns silently without informing the nature of the value.
Optional is acting as a Container, It holds the reference and provides some method to test the reference inside is present or absent.
Let see How we can return Optional with above example.

package com.example.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class OptionalTest {
private static List<String> nameList = new ArrayList<String>();
static{
nameList.add("Shamik");
nameList.add("Samir");
nameList.add("Swastika");
}

public Optional<String> findName(String nameToFind){
return nameList.contains(nameToFind)?Optional.of(nameList.get(nameList.indexOf(nameToFind))):Optional.empty();
}

public static void main(String[] args) {
OptionalTest test = new OptionalTest();
Optional<String> searchedName = test.findName("Mayukh");
if(searchedName.isPresent()){
System.out.println("HI,"+ searchedName.get());
}else{
System.out.println("Name not found");
}
}

}




Here, I use Optional.of() method which creates a new Optional object with the value passed in the 'of' method as a parameter, and if the value is not found in nameList I return and Empty optional which does not contain anything, don't say it contains a null, Empty represents the Value is absent, In this way we say to the caller, my method may gives you a result which does not contain anything so prepare for it.
PO : Master Oogways I understood your point but still I have  confusions, here caller has to check if(Optional.ispresent()) to get a value which is present but if caller forget to do this check, It gives you a NoSuchElement Exception, So what is the value to use optional -- seems it changed the null pointer exception to NoSuchElement Exception, nothing else, I don't see a point here to use Optional, It can't shield us from Null Pointer Exception.
Oogway: Ha Ha, That's why I choose you as a Dragon Warrior, You are so intelligent and to the point, You learned new things very quickly. Let me share you some thoughts,
Null is Omnipresent no one can never ever remove or defeat it completely, What we can do is protect ourselves from null, educate our Java villagers from the rage of nulls.
Optional is like a warning bell in the city, rather than nulls come silently, By Optional API developers always warned  Java Villagers/ or callers, Null can be entering your village at any point of time.
So my point is, till now only efficient villagers or callers understand when to use, not null check to escape from Null pointers rage but still in a complex call or lots of chained calls they fall in the null pointers trap. Optional tries to fix that it gives remind about absent values. Absent values can come so  protect your call from that or rather always use Optional.ispresent() check with Optional.get.
Optional does not remove the null pointer exception it warns caller to handle the absent scenarios.
It is not a Technical improvement rather it is a Conceptual improvement added into Java8 which educate java programmers to handle a scenario where value can be present or absent.

PO: I realize this Master Now tell me the Best practices of Optional.
Oogway: I am too late for today, Please come Tomorrow I will discuss best practices.

Conclusion: Oogway taught us a valuable lesson Optional is not a replacement for the null check rather it tries to say caller about the nature of the returns value and implicitly reminds caller to handle the absent cases. If Caller forgets to do that it will end up with the NoSuchElementException, which is a clear evidence you are trying to do an operation where the element/value is not present. It is a big conceptual improvement, it encourages caller to handle absent cases, unlike null return value where the caller has a confusion API developer already tackle the null value or I have to do this?






Java8 : All about Method reference


Java8 brings many features which help us to code like Functional programming in an OO context. One of the important and useful features is method reference, In this article, we will do a detailed discussion about method reference.

What is a Method reference?
In Java8, Method reference is a concept, by which we can point a method, But think about OO context if we need to use a method of another class what we generally do, we compose that Object -- HAS-A relationship/or pass that Object as a parameter,  into a method then call the desired method by "." operator <instance.methodName()>, but think-- To use just one method we have to carry the whole object, it would be great if we can directly pass that method like a variable. By method reference, we can do the same.

How does Method reference work?
By:: operator, If we invoke a method, it gives us the method refrence, But think in OO context, we can't do any operation without an Object, and Java is an OO language so how we can pass only a method, The answer is -- java8 Functional Interface, It is an interface with one and only one abstract method,  Java8 use that interface concept intelligently, we know by an interface we can polymorphically accept any implementation so If we think, method reference as a Functional interface  and method matching this Functional interface is an implementation then we can pass any method which matches the signature of Functional interface.In simple term when we invoke a method using:: it wraps that method in a Functional interface, and the only abstract method of the Functional interface inferred the type and signature from the method, its referenced by::. So any functional Interface whose signature match with the method signature of the invoked method is a potential candidate for hold the method reference, similarly, any method whose signature match with the Functional interface signature can be invoked or passed.

Let see a simple example,

package com.example.methodref;
import java.util.function.Consumer;
public class Utility {
public void display(String content,Consumer<String> disPlayMedium){
disPlayMedium.accept(content);
}
public void displayIntoProjector(String content,Projector projector){
projector.display(content);
}
public Projector createProjector() {
return new Projector() {
@Override
public void display(String content) {
System.out.println(content);
}
};
}
public static void main(String[] args) {
Utility utility = new Utility();
Projector projector = utility.createProjector();
utility.display("Hello Shamik using Lambda", content->System.out.println(content));
utility.display("Hello Shamik Using Method refrence", System.out::println);
utility.display("Hello Shamik Using Projector Functional Interface", projector::display);
utility.displayIntoProjector("Hello Shamik using Lambda", content->System.out.println(content));
utility.displayIntoProjector("Hello Shamik using Methodrefrence", System.out::println);
utility.displayIntoProjector("Hello Shamik using explicit Projector", projector::display);
}
}

Deep dive into the Code :
Here I create a simple program, which displays a message, for the same I create a display method which takes a message and a medium where the message should be displayed like the console, projector etc.
The display method takes a string, and a consumer functional interface, Consumer's accept method takes a string and returns nothing. So we can invoke display method using lambda expression which takes an argument and print that.
utility.display("Hello Shamik using Lambda", content->System.out.println(content));
But wait, think about the method signature of println(), it takes a string and return nothing/void, so it's signature match with Consumer 's accept method so as per method reference if any method signature match with functional interface signature we can use method reference so we easily use method reference to println
our code look like,
utility.display("Hello Shamik Using Method reference", System.out::println);
look here I am not passing any parameter to a printing method, so the obvious question is what it should print the answer lies in the method display
public void display(String content,Consumer<String> disPlayMedium){
disPlayMedium.accept(content);
}
in that method, we actually apply the display medium to the content we pass,  by method reference we defer the call and apply the call when required unlike the method call using. operator.
Now, we want to display our content into a projector so we will create a projector interface like following.

package com.example.methodref;
public interface Projector {
public void display(String content);
}

One thing is noticeable here, the signature of the display method of projector interface is same as Consumer interface accept method. as Utility class display method takes Consumer as an argument we can pass the Projector's display method as a reference so we can write the following

utility.display("Hello Shamik Using Projector Functional Interface", projector::display);
In the same way, now we create another method called displayIntoProjector which takes content and the projector interface as a display medium. so we use our own Projector interface rather than using Java8 Consumer interface, but notice that we can call this method same as we called the display method, so Our own interface also acts as a functional interface and can hold method reference.

Till, this point we have a fair understanding How Method reference works, Now we will discuss the type of method reference.
There are 4 types of method reference
1. Reference to a static method.
2. Reference to an instance method of a particular object.  
3. Reference to an instance method of an arbitrary object of a particular type.  
4. Reference to a constructor.

1. Reference to a static method:If we need to pass a reference to a static method we can do so, Signature of the static method should be matched with the Functional interface.
see the below example

package com.example.methodref;
import java.util.function.Consumer;
public class Utility {
public void display(String content, Consumer<String> disPlayMedium) {
disPlayMedium.accept(content);
}
public static void writeOnPapaer(String content){
System.out.println("On paper ::" + content);
}
public static void main(String[] args) {
Utility utility = new Utility();
utility.display("Hello Shamik Using static method reference", Utility::writeOnPapaer);
}
}

Here I have written one static method called writeOnPaper whose signature is same as Consumers accept, so we can invoke the writeOnPaper using Utility::writeOnPapaer.

2.Reference to an instance method of a particular object:Sometimes we need to pass a method as a method reference which holds a state of it's enclosing Object, so that method is holding a state of an Outside variable/ member variable, So we have to use that particular object instance when the method invoked by another method, So it is utmost important to pass that Object context also.
Corresponding lambda would be
(object)->object.someMethod(object)
so, In a simple term, if we need to reference a method which is not stateless, in that case, we will call that method using the same instance so that state will be preserved.
see the example,

package com.example.methodref;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class Utility {
private String fixedContent ="Hello this is a default content";
public void changeTheStateOfFixedContent(String content){
fixedContent = content;
}
public String displayFixedContent() {
return fixedContent;
}
public static void main(String[] args) {
Utility utility = new Utility();
utility.changeTheStateOfFixedContent("Changing the State");
Supplier<String> supplier = utility::displayFixedContent;
System.out.println(supplier.get());
Supplier<String> newsupplier = new Utility()::displayFixedContent;
System.out.println(newsupplier.get());
}
}

See, the example carefully here I have a fixedcontent which will be returned by the method displayFixedContent, Now I add another method called changeTheStateOfFixedContent by which we change thebody of fixedContent i.e changing the state.
Now in main when I create a Utility Object instance and change the fixed Content by invoking utility.changeTheStateOfFixedContent("Changing the State");
after that, I use same object instance when I invoke the displayFixedContent method as a reference SO that changed content is preserved. and when I do the call supplier.get() I got the output Changing the State which was set earlier.
But look the second call here I create a new Utility Object and invoke the displayFixedContent method as the reference. The new Object does not know about the changed state so it shows default message Hello this is default a content.
So the crux is when a method uses a state/member variable of the enclosing Object, we should use that particular object to invoke the method as a reference.
3. Reference to an instance method of an arbitrary object of a particular type :  If an instance method is stateless, that is it does not use any member variable which holds a particular state then we can use any reference of that class to invoke the method as a reference because we want to reuse that method and method does not hold any state.

like the display method in Utility class it does not hold any member so invoke the same we can use any object instance of Utility let see the example

package com.example.methodref;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class Utility {
public void display(String content, Consumer<String> disPlayMedium) {
disPlayMedium.accept(content);
}
public static void main(String[] args) {
Utility utility = new Utility();
BiConsumer<String,Consumer<String>> biConsumer = utility::display;
biConsumer.accept("Hi This is a Test", System.out::println);
BiConsumer<String,Consumer<String>> biConsumerAgain = new Utility()::display;
biConsumerAgain.accept("Hi This is a Test", System.out::println);
}
}

See that as the display is stateless in both cases we got the same output "Hi This is a Test".
4. Reference to a constructor:  we can use constructor as a method reference also, By doing this we not create the Object immediately unlike new SomeObject(), we defer the Object creation and when the Object is actually required we create them. Now if you look the signature of new you see it does not take any argument but produce an instance of a class, so it acts as Java8 Supplier interface which takes nothing but returns an Object, So we can use Supplier as the reference to the constructor.

Let see the example

import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class Utility {
private String fixedContent ="Hello this is default content";
public String displayFixedContent() {
return fixedContent;
}
public static void main(String[] args) {
Supplier<Utility> utilitySupplier = Utility::new;
String body = utilitySupplier.get().displayFixedContent();
System.out.println(body);
}
}


Conclusion: Method reference is an important concept, By the same, we can pass a method into a higher order method without passing the Object as a whole.