5,776 views
1 Star2 Stars3 Stars4 Stars5 Stars (9 votes, average: 5.00 out of 5)
Loading ... Loading ...

18.04.11

Neat Trick for Returning an Empty List in Java

Posted in Blogroll, Photos, Random Thoughts, Tech at 1:04 pm by Liv About Liviu Tudor

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.

Disclaimer

Leave a Comment