How to avoid many null checks when using get () in a Java collection?

I have the following statement

getLD().get(cam.getName()).getAGS().get(aG.getName()) 

getLD (), getAGS () returns Java collections

I would not consider this an error if getAGS() were empty, and if the result of getAGS().get(aG.getName()) was empty. However, it is rather dirty and a little pain checking these zero conditions.

eg. if(getLD().get(camp.getName()).getAGS() !=null && getLD().get(cam.getName()).getAGS().get(aG.getName()) != null) {

Can anyone suggest a better way to handle this? Obviously, I could create the variable x = getLD().get(camp.getName()).getAGS() to shorten the code, but is there a way in which I would not need to perform two checks for null?

All help is much appreciated!

+4
source share
6 answers

IMO, the best strategy is to design your data structures so that there are no zeros in the first place. For example, use empty collections or arrays with zero length or "" instead of null . For application classes, consider using a special instance that you can use instead of null .

The second strategy is to replace the use of open shared data structures (for example, maps, lists, arrays) with custom classes. This hides implementation details within the class and allows the use of Java static typing to avoid many situations where null checking is required.

The third strategy is to create a helper class with a bunch of methods that implement common operations; for example "get Cam for LD". (IMO, this approach is a bad alternative compared to others, but at least it reduces the number of times the code is repeated.)

To the extent that you cannot get rid of zeros, you have no choice but to explicitly check them. (There was a proposal to add the "elvis" operator to Java 7 as part of the Coin project, but unfortunately it has been shortened.)

+3
source

The best way is to avoid the chain. If you are not familiar with the Law of Demeter (LoD), in my opinion, you should. You gave a great example of a conversation that is too close to classes in which it has no business, knowing anything.

Demeter's Law: http://en.wikipedia.org/wiki/Law_of_Demeter

+3
source

The apache commons project has a library called Bean Introspection Utilities (BeanUtils), which looks like it can do what you need. Check out the access section of nested properties in the user guide and see the BeanUtils class:

http://commons.apache.org/beanutils/

It has utility classes that I think can do what you need.

Another thing to keep in mind: you should try to avoid this many levels of access to nested properties. This is the smell of code called β€œfunction envy” when an object wants to regularly use the functions of another object. Consider creating methods on a top-level object, or find a way to redesign to make an available function more accessible.

+1
source
 try { foo().bar().baz(); } catch (NullPointerException e) { // Check if it was actually an error } 
0
source

Code in groovy !.

Not always possible depending on your environment and performance requirements. But his joy is just to type

 if (getLD(camp?.GetName())?.getAGS(ag?.GetName())) 

Alternatively, you can simply encode what you mean and catch the null pointer exception. In your case, that would be much more readable, especially from you, without worrying about which element is null.

0
source

I think something is more complete than necessary if you need to do

 getLD().get(cam.getName()).getAGS().get(aG.getName()) 

If you need to check if the second collection or the result is null, you can do something like:

 Map<?,?> firstList= getLD(); Object value = null; if (firstList!=null && !firstList.isEmpty() && fistList.containsKey(cam.getName())){ Map<?,?> secondList = firstList.get(cam.getName()); if (secondList!=null && !secondList.isEmpty() && secondList.containsKey(aG.getName())){ value = secondList.get(aG.getName()); } } if(value != null){ // Do the required operations if the value is not null }else{ // Do the required operations if the value is null } 

With this code, I checked if the first set is not null, is not empty, and has content. I get the second collection, and I repeated this process in the second collection.

Also, to create this operation, a method can be created:

 private Map<?,?> getItem(Map<?,?> map,Object key){ if (map!=null && !map.isEmpty() && map.containsKey(key)){ return map.get(key); } return null; } 

and in your code:

 Object value = getItem(getItem(getLD(),cam.getName()),aG.getName()); if(value != null){ // Do the required operations if the value is not null }else{ // Do the required operations if the value is null } 
0
source

All Articles