We all have done it, in fact, I’m in the process of changing my APIs over to not do.  Returning NULL for a return type.  After doing some work with streams, I see that return NULL often adds additional complexity to the code.  In this article, we are going to discuss what to return besides NULL.

Empty Collection v’s NULL

If your method returns a NULL for when there are no objects in the list, or on an error condition, your calling code is going to have to look like this:

List<PersonDTO> allPeople = this.getAllPeople();
		
		if(allPeople != null) {
			allPeople = allPeople.stream().filter(person -> person.getLastName().equals("Ghost")).collect(Collectors.toList());
		}

Now if getAllPeople() was guaranteed to not return NULL you could do this:

List<PersonDTO> allPeople = this.getAllPeople().stream().filter(person -> person.getLastName().equals("Ghost")).collect(Collectors.toList());

 It’s a simple change anywhere that you were doing a “return null;”  change to “return Collections.emptyList();” think about how much easier your code would be to write.

Type of CollectionCollections Method
java.util.Enumeration<E>Collections.emptyEnumeration()
java.util.Iterator<E>Collections.emptyIterator()
java.util.List<E>Collections.emptyList()
java.util.ListIterator<E>Collections.emptyListIterator()
java.util.Map<K.V>Collections.emptyMap()
java.util.NavigableMap<K,V>Collections.emptyNavigableMap()
java.util.NavigableSet<E>Collections.emptyNavigableSet()
java.util.Set<E>Collections.emptySet()
java.util.SortedMap<K,V>Collections.emptySortedMap()
java.util.SortedSet<E>Collections.emptySortedSet()

Empty Stream v’s NULL

While I am not a fan of returning a Stream from a method.  The above example works just as well if your returning a stream.  To return an empty stream use “Stream.emtpy()”

Empty Arrays v’s NULL

Again having an object instead of having to check for NULL, is the desired outcome.  However at the same time you do not want to be wasteful with memory.  When it comes to returning an Empty Array one of the best solutions is to use a constant:

private static final PersonDTO[] NO_PEOPLE = {};
	
public PersonDTO[] getAllPeople() {				
	return PersonDTO.NO_PEOPLE;
}

Your not needing to create an empty array each time, it’s reusable across all of your code.

Single Object v’s NULL

Now then this is when things get fun.  What do you do when your returning a single object?  When it is not an Array, Stream, List, Map, Iterator, or Enumeration.  Well often times we return objects on our method calls.  This doesn’t have to change, but if your method is one that could return NULL, then maybe you should consider returning an “Optional”.  Now with Optional you can return “Optional.empty()” instead of a NULL.  In cases where you are returning your Object, you use “Optional.of(yourObject)”.

This provides a built in portion of the NULL Pointer check for the user of your method call.  A simple call to the “isPresent()” method call will tell us if we have a value or not.  This makes the code far easier to read. 

What if you have to return NULL?

Sometimes there isn’t a way around it.  Either it’s legacy code and you have to maintain the code in that form, or some other reason you deem you must return a NULL.  Well take a small step to help the user of your method to know if may return a NULL.  Use the “@Nullable” annotation to signal to the user this method call can return a NULL.


Discover more from GhostProgrammer - Jeff Miller

Subscribe to get the latest posts sent to your email.

By Jeffery Miller

I am known for being able to quickly decipher difficult problems to assist development teams in producing a solution. I have been called upon to be the Team Lead for multiple large-scale projects. I have a keen interest in learning new technologies, always ready for a new challenge.