49

I want to check the list is empty or not if not proceed further. So, which is preferable in apex and what are the differences between them?

 if(myList.size() > 0) or 
 if(!myList.isEmpty())  or 
 if(myList != null)  

5 Answers 5

89

Generally, your lists should always be initialized. One common misconception is that queries can produce a null list, which is never true.

For example, consider the following code:

Account[] records = [SELECT Id, Name, AccountNumber FROM Account];
if(records!=null && !records.isEmpty()) {
    for(Account record: records) {
        // Do Something Here
    }
}

This is a waste of CPU time, because (a) records will never be null, and (b) iterating over an empty list is acceptable. Therefore, none of the three checks you might use are rarely appropriate. The only exception to this rule is when one query is used to fuel another query, in which case you would check for the presence of values before performing the query:

Account[] accounts = [SELECT Id, Name, AccountNumber FROM Account];
if(accounts.isEmpty()) {
    return;
}
Contact[] contacts = [SELECT Id, Name, Email FROM Contact WHERE AccountId IN :accounts];

For lists you create yourself, you should always initialize them before using them. This is true for other types, like sets and maps, as well. There are, however, times when you'll need to check for a specific condition before using some lists. It helps if you experiment with the various types to get a feel for when you should be aware that a list may be null.

For example, consider a variable that binds to a multi-select picklist:

public String[] selectedValues { get; set; }

In this case, selectedValues will either be null, or will not be empty. You only ever need to check for != null in this case. Part of becoming an efficient developer is recognizing the patterns in a system. If you're still using myVar != null && !myVar.isEmpty() as a condition, that generally means you're making one or even two checks too many.

There is always one correct condition to use in every situation. If this isn't true, that suggests that values were not properly initialized elsewhere.

Edit: Safe Navigation Operator

As a special exception, you can now use the Safe Navigation Operator to skip the null check. That looks like this:

if(records?.size() > 0) {
 /* Do something here */
}

Because of the changes brought in with the Safe Navigation Operator, when either size of the comparison is null, the result is false. If we want to abort early, then we can negate the entire thing:

if(!(records?.size() > 0)) {
  return;
}
8
  • 1
    sometimes, for your second code snippet; I might have Account[] accounts = [SELECT Id, Name, AccountNumber FROM Account]; Contact[] contacts = !accounts.isEmpty() ? [select id, name, .. from Contacts where accountId in accounts] : new List<Contact>(); in case I need to keep going down the method for other things - knowing that my code can handle either empty account list or empty contact list
    – cropredy
    Commented May 22, 2015 at 20:22
  • 2
    True enough. Sometimes you need to continue, sometimes not. The basic premise is that this should be the only time you need to even see if the list is empty, because it usually doesn't matter.
    – sfdcfox
    Commented May 22, 2015 at 20:37
  • why should we always initialize lists or other types like sets or maps ?
    – Walker
    Commented May 29, 2015 at 3:49
  • 2
    i think if we initialize a variable of any type, some resource will be consumed. So i initialize with null, which is implicit as well, and assign it with result of some method, and then while using it, check if it is not null. is there something wrong with this approach in salesforce / apex ? i think return type of SOQL is never null, so if we assign an initialized list with SOQL result, we check for its size >0 and even if its uninitialized, checking for size may not be an issue due to the type SOQL returns, but if we assign a list with value returned by another method it ma y be an issue.
    – Walker
    Commented May 29, 2015 at 17:20
  • 2
    See articles such as elegantcode.com/2010/05/01/say-no-to-null. Null checking bloats code. Avoid bugs.
    – sfdcfox
    Commented May 29, 2015 at 19:03
14

It is generally best to avoid null values in code so using null list references to indicate empty lists isn't usually good approach. That is this code:

List<String> strings = new List<String>();
...
for (String item : strings) {
    ...
}

is clearer and safer than this code:

List<String> strings = null;
...
if (strings != null) {
    for (String item : strings) {
        ...
    }
}

So prefer empty lists to null list references.

Personally I find myList.size() > 0 to be clearer than !myList.isEmpty() because the latter amounts to "not is empty" which takes a moment to understand. But as people will use both forms get used to both.

3
  • 3
    In the past I was told by SFDC engineering during a code review that .isEmpty() is more efficient than .size() == 0 due to the fact that it's one operation rather than a method call and then a comparator evaluation. I don't know how much more efficient it can truly be, since isEmpty is essentially doing that very same operation within its own scope.
    – Mark Pond
    Commented May 22, 2015 at 16:30
  • 4
    @MarkPond Wow. Even if there is a difference, I would assume that it would only have any impact in the most contrived piece of code. Lets remember that database calls are thousands of times slower than simple lines of code. Guess they couldn't find anything else to comment on in your code...
    – Keith C
    Commented May 22, 2015 at 16:36
  • 12
    I hate to burst bubbles, but I just tested this. ! isEmpty() is slower than size() > 0, and isEmpty() is the same as size() == 0. However, even so, difference was less than 30ms per 1 lakh (100k) iterations.
    – sfdcfox
    Commented May 22, 2015 at 20:44
1

Personally I prefer myList.isEmpty(). myList.size() will throw error if myList is null. myList != null will pass if the list is initialized and empty, which is not what you want. So usually a combination condition (myList != null && !myList.isEmpty()) or (myList != null && myList.size()>0)

1
  • 13
    myList.isEmpty() will also NPE is myList is null.
    – Keith C
    Commented May 22, 2015 at 15:59
1

Just an idea: in your Utils/Common methods class, add a method to check if the list is null or empty.

Something like:

public static Boolean listIsNullOrEmpty(SObject[] objects) {
    return (objects == null || objects.isEmpty());
}

Since it accepts a list of SObjects in the parameter, this method becomes more generic, then you can use for Accounts, Opportunities or any other list of SObjects you want.

As a reminder:

list == null  //Null check
list.isEmpty()  //Check if its blank
list.size() == 0  //Compare size
0

Try initializing Lists if they are null before you need to use them.

Date[] dates = api.getDates();
dates = dates == null ? new Date[]{} : dates;
dates.add(Date.today());

or

String[] names = api.getNames();
for(String name : names == null ? new String[]{} : names){
    ....
}

or

Map<Id, Map<Id, Contact>> accountContacts = new Map<Id, Map<Id, Contact>>();
for(Contact contact : [
    SELECT Id, AccountId
    FROM Contact
]){
    Map<Id, Contact> contacts = accountContacts.get(contact.AccountId);
    contacts = contacts == null ? new Map<Id, Contact>() : contacts;
    contacts.put(contact.Id, contact);
    accountContacts.put(contact.AccountId, contacts);
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .