Neat Trick for Returning an Empty List in Java

Posted by & filed under , , , .

I’ve found this post actually burried in my “Drafts” — it’s been there for sometime it seems. I recall writing about it on my mobile WordPress application, so I’m guessing I’ve saved it as draft on the blog with the view to apply the code pretty-printing and forgot about it quite likely 🙂 So I thought I’d resurrect it as I have used this a few times myself.

In quite a few instances when I was coding in Java, I found myself writing methods that were returning collections — in this particular case I’m going to refer to instances of List in particular, but the idea can be applied to other collections I’m sure. Normally when returning a list, I saw most people writing this sort of code:

...
public List getUsers(String clientName) {
  int clientId;
  //retrieve the client id based on clientName - e.g. from database etc
  ...
  //we assume clientId should be zero or above
  List users = null;
  if( clientId > 0 ) {
     users = new ArrayList();
     //now append all the users to this list
     ....
  }
  return users;
}
...
//code calling the above function
public void displayUsers(String clientName) {
  List users = getUsers(clientName);
  if( (users == null) || (users != null && users.size() == 0) ) {
     //if getUsers doesn't return any users then the for below doesn't execute and we don't display anything
  else {
    ...
  }
}

As I signalled above, the line I’m not happy with is

  if( (users == null) || (users != null && users.size() == 0) ) {

Granted, with the usage of Apache Commons Collections, this can be written as:

  if( CollectionUtils.isEmpty(users) ) {

However, this just makes the code easier to understand and write — but under the cover there is still the same test being operated. Rather than returning null in such cases, I always prefer to return instead an empty List — mostly because I structure my code such that if the list is empty, a for loop won’t get executed. So for instance I would prefer to re-write the displayUsers function above as follows:

...
public void displayUsers( String clientName ) {
  List users = getUsers( clientName );
  //if getUsers doesn't return any users then the for below doesn't execute and we don't display anything
  for( String user : users ) {
    ...
  }
}

This does mean however, that if getUsers returns null we end up with a nice NPE (NullPointerException). So ideally we want to ensure that getUsers never returns null. One way to do this is to ensure a fresh ArrayList instead of null:

...
...
public List getUsers(String clientName) { 
  int clientId; //retrieve the client id based on clientName - e.g. from database etc 
  ... 
  //we assume clientId should be zero or above 
  List users = new ArrayList(); 
  if( clientId > 0 ) { 
    //now append all the users to this list 
    ... 
  } 
  return users; 
} 
... 
//code calling the above function
public void displayUsers(String clientName) {
 List users = getUsers( clientName );
  //if getUsers doesn't return any users then the for below doesn't execute and we don't display anything
  for( String user : users ) {
    ...
  }
}

This however, means that for each call we could end up creating a new ArrayList just for the purpose of returning an empty List — which needless to say it’s not desireable in a high throughput system as this memory will be marked “ready for garbage collection” after the call to displayUsers. So ideally we want to avoid creating new List‘s every time getUsers. This can be done by declaring a static final constant and set it to an empty list:

...
private static final List EMPTY_LIST = new ArrayList();
...
public List getUsers(String clientName) { 
 int clientId; //retrieve the client id based on clientName - e.g. from database etc 
 ... 
 //we assume clientId should be zero or above 
 List users = EMPTY_LIST; 
 if( clientId > 0 ) { 
   users = new ArrayList();
   //now append all the users to this list 
   ... 
 } 
 return users; 
}

This seems to do it however, there’s still a big problem — while EMPTY_LIST is declared final, it means that no one can modify the reference, but it doesn’t mean we cannot modify the contents of it! So if the code that calls getUsers might occasionally modify the return value for whatever reasons, we can end up with the EMPTY_LIST instance no longer being empty (if some code adds String‘s to it!). One way to prevent this, is to use the Collections.unmodifiableList function in JDK which will ensure your EMPTY_LIST stays empty:

...
private static final List EMPTY_LIST = Collections.unmodifiableList( new ArrayList() );
...
public List getUsers(String clientName) { 
 int clientId; //retrieve the client id based on clientName - e.g. from database etc 
 ... 
 //we assume clientId should be zero or above 
 List users = EMPTY_LIST; 
 if( clientId > 0 ) { 
   users = new ArrayList();
   //now append all the users to this list 
   ... 
 } 
 return users; 
}

Not a big trick to be honest, but I found out it helps.

2 Responses to “Neat Trick for Returning an Empty List in Java”

  1. Dave Schumann

    This should be virtually as fast and looks much cleaner for returning an always-empty list:

    if (clientId <= 0) {
    return Arrays.asList()
    }

  2. Liv

    You are right, however, the List you are returning DOES allow for the caller to modify it — which was half the point I was trying to make. If you are returning an empty list just to signal there is nothing to return, then I’d stick to my approach, to ensure the client doesn’t modify it (and also share one single instance across all code, thus saving on memory and time to create these instances).
    If however, you need your caller to add/delete things from the list, your approach is quite likely the better one.
    Thank you for your comment though!