Guava Optional Class Example
Problem with Null Pointers — using Guava’s Optional Class
Ever since I can remember NullPointerExceptions (NPEs) have been a source of frustration and problems in many of the projects I have been involved in, current project included. Primarily, due to the fact that null is ambiguous and does not relay to the developer or the user what a null is supposed to mean. For example, Hashmap.get(key) may return a null when the key is not found in the Hashmap but it may also return a null if the key exists but the value is null. Throughout the years we have developed our own classes that handle this ambiguity for us, but by making use of Guava’s Optional class we have the added advantage of leveraging the mass of the open source community both in terms of testing capability and the sheer number of folks using Google’s Guava code base.
“I call it my billion-dollar mistake” — Sir Tony Hoare, on his invention of the null reference
Guava’s Optional class
You will use Guava’s Optional class anywhere you might expect to use a null object. The Optional class itself does not have any constructors and instead uses three static methods for creating an instance of that class. Optional.of(T) assumes the value of T will not be null, if it is it will fail fast and throw a NullPointerException (NPE).
The second available static method for creating an instance Optional is the Optional.fromNullable(T) which works very similar to Optional.of(T) except that it will work with both null and non-null values and returns Optional instance containing the wrapped contents of the reference T if it was non-null value, otherwise it returns Optional.absent().
The third static method for creating an instance Optional is the Optional.absent(). This returns an Optional instance with no reference contained in it and is mostly used when you know that the value being returned will be null.
By using Guava’s Optional class we reduce and replace null references with non-null values. The instance of Optional, will contain a non-null T reference (which is to say, the reference is “present”). Or the Optional instance will contain nothing (which is to say the Optional, is “absent”). However, at no point will the Guava’s Optional contain null. The point of using Optional, is to make the user of your API or class to think about the possibility of the value not being present.
Static Methods to Create Instance of Optional
# | Method | Description |
---|---|---|
1 | Optional.of(T) | Assumes the value of T will not be null, if it is it will fail fast and throw a NullPointerException (NPE) |
2 | Optional.fromNullable(T) | Accepts both null and non-null values and returns Optional instance containing the wrapped contents of the reference T if it was non-null value, otherwise it returns Optional.absent() |
3 | Optional.absent() | Return an absent Optional of the type specified |
Methods available to Optional instance
As you will see in the examples below, once you have an instance of Optional you can use instance methods described below.
# | Method | Description |
---|---|---|
1 | boolean isPresent() | This method returns true if the Optional instance contains (non-null) reference |
2 | T get() | Returns the contained instance of T, provided it exists. Otherwise, it throws an IllegalStateException. |
3 | T or(X) | Returns the contained instance of T if it exists, otherwise it returns the default value specified in X. |
4 | T orNull() | Returns the contained instance of T if it exists, otherwise it returns null. |
5 | Set | Returns an immutable singleton Set containing the instance in this Optional, otherwise it will return an empty immutable set. |
Sample Usage
Using isPresent() Method
if (optionalPerson.isPresent()) { System.out.println("Instance optionalPerson has a value present..."); } // Returns true is instance contains (non-null) value System.out.println("isPresent...: " + optionalPerson.isPresent());
optionalPerson.isPresent() Output

Instance optionalPerson has a value present... isPresent...: true
Using get() Method
Integer myFileID = new Integer(10); Optional<Integer> fileId = Optional.fromNullable(myFileID); if (fileId.isPresent()) { System.out.println("Current fileID is: " + fileId.get()); }
fileId.get() Output

Current fileID is: 10
Using or() Method
... Optional<String> myFile2 = Optional.fromNullable(filename2); String defFileName2 = myFile2.or("hello.txt"); // Using Java Ternary Operator is the equivalent String defaultFileName2 = (filename2 != null) ? filename2 : "hello.txt"; System.out.println("defaultFileName2...: " + defaultFileName2); System.out.println("defFileName2.......: " + defFileName2);
myFile2.or(“hello.txt”) Output

defaultFileName2...: picture.png defFileName2.......: picture.png
Using orNull() Method
Integer myFileID = new Integer(10); Optional<Integer> fileId = Optional.fromNullable(myFileID); Optional<Integer> fileIdNull= Optional.fromNullable(myFileIDNull); if (fileId.isPresent()) { System.out.println("Current fileID is: " + fileId.get()); } System.out.println("Current fileIDNull is: " + fileIdNull.orNull());
orNull() Output

Current fileID is: 10 Current fileIDNull is: null
Project Structure
GuavaOptionalExample.java
package com.avaldes.tutorial; import com.avaldes.model.Person; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; public class GuavaOptionalExample { public static void main(String[] args) throws JsonProcessingException { // Creating Person object using setter methods not in the constructor Person p = new Person(); p.setFirstName("John"); p.setLastName("Miller"); p.setAge(35); p.setGender("M"); p.setStreetAddress1("100 Main Street"); p.setCity("Fort Lauderdale"); p.setStateProvince("Florida"); p.setCountryName("United States"); Person p1 = new Person("Elizabeth", "Jackson", 13, "F", "32 Oak Street", "Apt3C", "Waterloo", "Alabama", "United States", null); System.out.println("-------Java Object -- toString()---------"); System.out.println(p.toString()); System.out.println(p1.toString()); System.out.println("--------- JSON ---------"); ObjectMapper jsonMapper = new ObjectMapper(); System.out.println(jsonMapper.writeValueAsString(p)); System.out.println(jsonMapper.writeValueAsString(p1)); System.out.println("------ JSON PRETTY PRINT -------"); jsonMapper.configure(SerializationFeature.INDENT_OUTPUT, true); System.out.println(jsonMapper.writeValueAsString(p)); System.out.println(jsonMapper.writeValueAsString(p1)); } }
Output

-------Java Object -- toString()--------- Person [firstName=John, lastName=Miller, age=35, streetAddress1=100 Main Street, streetAddress2=Optional.absent(), city=Fort Lauderdale, stateProvince=Florida, countryName=United States, children=Optional.absent()] Person [firstName=Elizabeth, lastName=Jackson, age=13, streetAddress1=32 Oak Street, streetAddress2=Optional.of(Apt3C), city=Waterloo, stateProvince=Alabama, countryName=United States, children=Optional.absent()] --------- JSON --------- {"firstName":"John","lastName":"Miller","age":35,"gender":"M","streetAddress1":"100 Main Street","streetAddress2":{"present":false},"city":"Fort Lauderdale","stateProvince":"Florida","countryName":"United States","children":{"present":false}} {"firstName":"Elizabeth","lastName":"Jackson","age":13,"gender":"F","streetAddress1":"32 Oak Street","streetAddress2":{"present":true},"city":"Waterloo","stateProvince":"Alabama","countryName":"United States","children":{"present":false}} ------ JSON PRETTY PRINT ------- { "firstName" : "John", "lastName" : "Miller", "age" : 35, "gender" : "M", "streetAddress1" : "100 Main Street", "streetAddress2" : { "present" : false }, "city" : "Fort Lauderdale", "stateProvince" : "Florida", "countryName" : "United States", "children" : { "present" : false } } { "firstName" : "Elizabeth", "lastName" : "Jackson", "age" : 13, "gender" : "F", "streetAddress1" : "32 Oak Street", "streetAddress2" : { "present" : true }, "city" : "Waterloo", "stateProvince" : "Alabama", "countryName" : "United States", "children" : { "present" : false } }
JavaNullCaseExamples.java
package com.avaldes.tutorial; import java.util.HashMap; import com.avaldes.model.Person; import com.avaldes.util.PersonMapper; import com.google.common.base.Optional; public class JavaNullCaseExamples { public static void main(String[] args) { String filename1 = null; Optional<String> myFile1 = Optional.fromNullable(filename1); String filename2 = "picture.png"; Optional<String> myFile2 = Optional.fromNullable(filename2); String defaultFileName1 = (filename1 != null) ? filename1 : "hello.txt"; String defFileName1 = myFile1.or("hello.txt"); String defaultFileName2 = (filename2 != null) ? filename2 : "hello.txt"; String defFileName2 = myFile2.or("hello.txt"); System.out.println("defaultFileName1...: " + defaultFileName1); System.out.println("defFileName1.......: " + defFileName1); System.out.println("defaultFileName2...: " + defaultFileName2); System.out.println("defFileName2.......: " + defFileName2); //----Implementation without Guava's Optional Class HashMap <Integer,Person> map = new HashMap<Integer,Person>(); Person p1 = new Person("Elizabeth", "Jackson", 27, "F", "32 Oak Street", "Apt3C", "Waterloo", "Alabama", "United States", null); Person p3 = new Person("Patrick", "Kilby", 42, "M", "192 Main Street", null, "Winston", "Virgina", "United States", null); Person p4 = null; map.put(1, p1); map.put(3, p3); map.put(4, p4); System.out.println("\n================================================"); System.out.println("Key is 1, value=" + map.get(1)); // Key #2 does not exist, will return null System.out.println("Key is 2, value=" + map.get(2)); System.out.println("Key is 3, value=" + map.get(3)); // Key #4 value is absent, will return null System.out.println("Key is 4, value=" + map.get(4)); PersonMapper pmap = new PersonMapper(); pmap.put(1, p1); pmap.put(3, p3); pmap.put(4, p4); System.out.println("\n================================================"); System.out.println("Key is 1, value = " + pmap.get(1)); // Key #2 does not exist, will return null System.out.println("Key is 2, value = " + pmap.get(2)); System.out.println("Key is 3, value = " + pmap.get(3)); // Key #4 value is absent, will return null System.out.println("Key is 4, value = " + pmap.get(4)); System.out.println("\n=[ Get Key==1, Check for Presence, orNull]======"); Optional<Person> optionalPerson1 = pmap.get(1); System.out.println("Key is 1, isPresent=" + optionalPerson1.isPresent()); System.out.println("Key is 1, value=" + optionalPerson1); System.out.println("Key is 1, orNull=" + optionalPerson1.orNull()); System.out.println("\n=[ Get Key==2, Check for Presence, orNull]======"); Optional<Person> optionalPerson2 = pmap.get(2); System.out.println("Key is 2, isPresent=" + optionalPerson2.isPresent()); System.out.println("Key is 2, value=" + optionalPerson2); System.out.println("Key is 2, orNull=" + optionalPerson2.orNull()); System.out.println("\n=[ Get Key==4, Check for Presence, orNull]======"); Optional<Person> optionalPerson4 = pmap.get(4); System.out.println("Key is 4, isPresent=" + optionalPerson4.isPresent()); System.out.println("Key is 4, value=" + optionalPerson4); System.out.println("Key is 4, orNull=" + optionalPerson4.orNull()); } }
Output

defaultFileName1...: hello.txt defFileName1.......: hello.txt defaultFileName2...: picture.png defFileName2.......: picture.png ================================================ Key is 1, value=Person [firstName=Elizabeth, lastName=Jackson, age=27, streetAddress1=32 Oak Street, streetAddress2=Optional.of(Apt3C), city=Waterloo, stateProvince=Alabama, countryName=United States, children=Optional.absent()] Key is 2, value=null Key is 3, value=Person [firstName=Patrick, lastName=Kilby, age=42, streetAddress1=192 Main Street, streetAddress2=Optional.absent(), city=Winston, stateProvince=Virgina, countryName=United States, children=Optional.absent()] Key is 4, value=null ================================================ Key is 1, value = Optional.of(Person [firstName=Elizabeth, lastName=Jackson, age=27, streetAddress1=32 Oak Street, streetAddress2=Optional.of(Apt3C), city=Waterloo, stateProvince=Alabama, countryName=United States, children=Optional.absent()]) Key is 2, value = Optional.absent() Key is 3, value = Optional.of(Person [firstName=Patrick, lastName=Kilby, age=42, streetAddress1=192 Main Street, streetAddress2=Optional.absent(), city=Winston, stateProvince=Virgina, countryName=United States, children=Optional.absent()]) Key is 4, value = Optional.absent() =[ Get Key==1, Check for Presence, orNull]================== Key is 1, isPresent = true Key is 1, value = Optional.of(Person [firstName=Elizabeth, lastName=Jackson, age=27, streetAddress1=32 Oak Street, streetAddress2=Optional.of(Apt3C), city=Waterloo, stateProvince=Alabama, countryName=United States, children=Optional.absent()]) Key is 1, orNull = Person [firstName=Elizabeth, lastName=Jackson, age=27, streetAddress1=32 Oak Street, streetAddress2=Optional.of(Apt3C), city=Waterloo, stateProvince=Alabama, countryName=United States, children=Optional.absent()] =[ Get Key==2, Check for Presence, orNull]================== Key is 2, isPresent = false Key is 2, value = Optional.absent() Key is 2, orNull = null =[ Get Key==4, Check for Presence, orNull]================== Key is 4, isPresent = false Key is 4, value = Optional.absent() Key is 4, orNull = null
Testing Java Using Nulls vs Guava Optional(MapExamples.java)
package com.avaldes.tutorial; import static com.google.common.base.Strings.emptyToNull; import java.util.HashMap; import com.google.common.base.Optional; public class MapExamples { public static void main(String[] args) { HashMap<String, String> myMap = new HashMap<String, String>(); myMap.put("Amaury", "Valdes"); myMap.put("Christy", "Smith"); myMap.put("", "Jackson"); myMap.put("John", "Angeline"); myMap.put(null, null); myMap.put("Bill", "Stanley"); myMap.put("Hailey", null); myMap.put("Stacy", "Newmann"); myMap.put("Kimmie", ""); displayValuesUsingJavaNulls(myMap); displayValuesUsingGuavaOptional(myMap); } public static void displayValuesUsingJavaNulls(HashMap<String, String> myMap) { System.out.println("-------[ displayValuesUsingJavaNulls ]-------"); for (String name : myMap.keySet()) { String value = myMap.get(name); if (name == null || name.isEmpty()) { System.out.print("Key: is empty or not available..."); } else { System.out.print("Key: " + name); } if (value == null || value.isEmpty()) { System.out.println(", Value: is empty or not available..."); } else { System.out.println(", Value: " + value); } } } public static void displayValuesUsingGuavaOptional(HashMap<String, String> myMap) { System.out.println("-------[ displayValuesUsingGuavaOptional ]-------"); for (String name : myMap.keySet()) { Optional<String> optionalKey = Optional.fromNullable(emptyToNull(name)); Optional<String> optionalValue = Optional.fromNullable(emptyToNull(myMap.get(name))); System.out.println("Key: " + optionalKey.or("is empty or not available...") + ", Value: " + optionalValue.or("is empty or not available...")); } } }
Output

-------[ displayValuesUsingJavaNulls ]------- Key: is empty or not available..., Value: is empty or not available... Key: is empty or not available..., Value: Jackson Key: Bill, Value: Stanley Key: Hailey, Value: is empty or not available... Key: Kimmie, Value: is empty or not available... Key: Christy, Value: Smith Key: Amaury, Value: Valdes Key: John, Value: Angeline Key: Stacy, Value: Newmann -------[ displayValuesUsingGuavaOptional ]------- Key: is empty or not available..., Value: is empty or not available... Key: is empty or not available..., Value: Jackson Key: Bill, Value: Stanley Key: Hailey, Value: is empty or not available... Key: Kimmie, Value: is empty or not available... Key: Christy, Value: Smith Key: Amaury, Value: Valdes Key: John, Value: Angeline Key: Stacy, Value: Newmann
Testing Java Using Nulls vs Guava Optional(ArrayListExamples.java)
package com.avaldes.tutorial; import java.util.ArrayList; import java.util.List; import com.google.common.base.Optional; import static com.google.common.base.Strings.emptyToNull; public class ArrayListExamples { public static void main(String[] args) { List<String> myList = new ArrayList<String>(); myList.add("Amaury"); myList.add("Christy"); myList.add("John"); myList.add(null); myList.add("Bill"); myList.add(""); myList.add("Stacy"); displayValuesUsingJavaNulls(myList); displayValuesUsingGuavaOptional(myList); } public static void displayValuesUsingJavaNulls(List<String> myList) { System.out.println("-------[ displayValuesUsingJavaNulls ]-------"); for (String name: myList) { if (name == null || name.isEmpty()) { System.out.println("Name: Value is empty or not available..."); } else { System.out.println("Name: " + name); } } } public static void displayValuesUsingGuavaOptional(List<String> myList) { System.out.println("-------[ displayValuesUsingGuavaOptional ]-------"); for (String name: myList) { Optional<String> optionalName = Optional.fromNullable(emptyToNull(name)); System.out.println("Name: " + optionalName.or("Name: Value is empty or not available...")); } } }
Output

-------[ displayValuesUsingJavaNulls ]------- Name: Amaury Name: Christy Name: John Name: Value is empty or not available... Name: Bill Name: Value is empty or not available... Name: Stacy -------[ displayValuesUsingGuavaOptional ]------- Name: Amaury Name: Christy Name: John Name: Name: Value is empty or not available... Name: Bill Name: Name: Value is empty or not available... Name: Stacy
Person.java
package com.avaldes.model; import java.util.List; import com.google.common.base.Optional; public class Person { private String firstName; private String lastName; private int age; private String gender; private String streetAddress1; private String streetAddress2; private String city; private String stateProvince; private String countryName; private List<Person> children; public Person() {} public Person(String firstName, String lastName, int age, String gender, String streetAddress1, String streetAddress2, String city, String stateProvince, String countryName, List<Person> children) { super(); this.firstName = firstName; this.lastName = lastName; this.age = age; this.gender = gender; this.streetAddress1 = streetAddress1; this.streetAddress2 = streetAddress2; this.city = city; this.stateProvince = stateProvince; this.countryName = countryName; this.children = children; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getStreetAddress1() { return streetAddress1; } public void setStreetAddress1(String streetAddress1) { this.streetAddress1 = streetAddress1; } public Optional<String> getStreetAddress2() { return Optional.fromNullable(streetAddress2); } public void setStreetAddress2(String streetAddress2) { this.streetAddress2 = streetAddress2; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getStateProvince() { return stateProvince; } public void setStateProvince(String stateProvince) { this.stateProvince = stateProvince; } public String getCountryName() { return countryName; } public void setCountryName(String countryName) { this.countryName = countryName; } public Optional<List<Person>> getChildren() { return Optional.fromNullable(children); } public void setChildren(List<Person> children) { this.children = children; } @Override public String toString() { return "Person [firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + ", streetAddress1=" + streetAddress1 + ", streetAddress2=" + getStreetAddress2() + ", city=" + city + ", stateProvince=" + stateProvince + ", countryName=" + countryName + ", children=" + getChildren() + "]"; } }
PersonMapper.java
package com.avaldes.util; import java.util.HashMap; import com.avaldes.model.Person; import com.google.common.base.Optional; public class PersonMapper { private HashMap<Integer, Person> hmap = new HashMap<Integer, Person>(); public PersonMapper() {} public void put(Integer key, Person value) { Person person = value; hmap.put(key, person); } public Optional<Person> get(Integer key){ Optional<Person> person = Optional.fromNullable(hmap.get(key)); return person; } }
That’s It!
I hope you enjoyed this tutorial. It was certainly a lot of fun putting it together and testing it out. Please continue to share the love and like us so that we can continue bringing you quality tutorials. Happy Coding!!!

Please Share Us on Social Media






Leave a Reply