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.
As suggested by Rahul, would recommend to add asserts in the test class to verify the data that is inserted/updated.
To answer, looking at the code, I assume that the line above if(onderdelen.Size() > 0)
is not evaluating to true. Hence the below and subsequent lines are not getting executed.
The line I am referring to is
if(u.Verkocht__c == true && u.Genereer_facturatieschijven__c == true)
As I don't see where these fields (Verkocht__c & Genereer_facturatieschijven__c )
are set in the test class
Best Answer
UPDATE, I now cover all four cases and tested in a different org so the raw numbers are different.
I agree that
isEmpty
is superior from a readability perspective. However, out of curiosity I ran each scenario 50,000 times. Thesize
method took .02334 seconds on average , whereas theisEmpty
method took .02139 seconds on average. That is a difference of around 9%. The difference appears negligible.Here is my methodology, perhaps less elegant than Mr. Ballinger's.