2

Here lately I have gotten into the habit of doing a two fold check on the maps that I create and I was wondering if it is even needed.

Lets just use a general map for this question:

Map<String, Boolean> mapStringToBool = new Map<String, Boolean>();

I'm wondering if I need to do the following before accessing the map, or if I can go straight to seeing if it contains a key. If I were to go straight to seeing if the map contains a key, would I get a 'dereference null object error' if the map had nothing in it yet.

if (mapStringToBool != null) {
  if (mapStringToBool.containsKey('Some Generic Key')) {
    //do something here
  }
}

This is more for my general knowledge and efficiency.

2 Answers 2

2

Your maps should never be null. This might mean that you initialize in a constructor, or it might mean that you initialize when the map is declared. Assuming you don't leave your maps null, then your check for a key will never throw an exception, even if the map is empty.

In general, you will define your maps in one of four ways:

// Constructor
public Klass() {
    myMap = new Map<String, Integer>();
}

// Query/SObject array
Map<Id, SObject> accounts = new Map<Id, SObject>([SELECT ... FROM ...]);

// In the stack
Map<Id, SObject> values = new Map<Id, SObject>();

// Lazy initialization
Map<String, Integer> values { get { if(values == null) values = new Map<String, Integer>(); return values; private set; } }

Any way you look at it, your map should never be null. The only time you need to check for null maps is if you're trying to use Trigger.newMap or Trigger.oldMap explicitly, or if you're using JSON methods.

I recently mentioned this before, but you should Say No To Null. Your code should never (well, almost never) need to check for null. This is a matter of efficiency. Checking nulls takes time, and time is a premium in Apex Code.

If the map is empty, you only need to check to see if there's a key present. If you write your code well, you can also assume that a non-null key also has a non-null value.

3

This is why I typically declare my maps using the final keyword. They can never be declared again and hence cannot be null.

final Map<String, Boolean> myMap = new Map<String, Boolean>();
if (!myMap.isEmpty()) // will never throw NullPointerException

You can still call as many methods on the map as you want.

myMap.put('key', true);
myMap.clear();
// etc.
5
  • If it is not null, then I would be able to skip to seeing if it contains a key correct? No error should be thrown in this case.
    – Tyager
    Jun 8, 2015 at 18:11
  • I'm doing a little reading on this and it sounds like final is very similar to constant. I would like to still be able to add to the map after instantiation. Will final prevent the map from changing?
    – Tyager
    Jun 8, 2015 at 18:13
  • Good stuff man. I threw it in Execute anonymous and it appears to work very nicely, and you can still use .put() on the map. I am also able to skip to .containsKey() and not get a dereference error. Good answer, I appreciate it.
    – Tyager
    Jun 8, 2015 at 18:20
  • So when I try to add something to the final map from another method you will be presented with the error 'Final member variables can only be assigned in their declaration statement or inside a constructor'. So, in a way, it is still a constant if you are outside of the constructor. Final would be good if I knew the map when I instantiated it, but I do not.
    – Tyager
    Jun 8, 2015 at 18:47
  • Final would be great in terms of doing everything in the constructor, but I am looking to be able to edit it in another method. Do you know of another way to create a map not equal to null?
    – Tyager
    Jun 8, 2015 at 18:48

You must log in to answer this question.

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