Как избежать множества проверок на null при использовании get () в Java Collection? - PullRequest
4 голосов
/ 11 августа 2010

У меня есть следующее утверждение:

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

getLD (), getAGS () возвращают коллекции Java

Я бы не считал это ошибкой, если бы getAGS() были пустыми,ни если бы результат getAGS().get(aG.getName()) был пустым.Тем не менее, это довольно грязно и немного мучительно для этих нулевых условий.

например if(getLD().get(camp.getName()).getAGS() !=null && getLD().get(cam.getName()).getAGS().get(aG.getName()) != null) {

Кто-нибудь может предложить лучший способ справиться с этим?Очевидно, я мог бы создать переменную x = getLD().get(camp.getName()).getAGS(), чтобы сократить код, но есть ли способ, которым мне не пришлось бы выполнять две проверки на ноль?

Вся помощь очень ценится!

Ответы [ 6 ]

3 голосов
/ 11 августа 2010

Лучше всего было бы избегать цепи. Если вы не знакомы с Законом Деметры (LoD), по моему мнению, вам следует. Вы привели прекрасный пример цепочки сообщений, которая слишком тесно связана с классами, о которых она ничего не знает.

Закон Деметры: http://en.wikipedia.org/wiki/Law_of_Demeter

3 голосов
/ 11 августа 2010

IMO, лучшая стратегия состоит в том, чтобы спроектировать ваши структуры данных так, чтобы в первую очередь не было нулей.Например, используйте пустые коллекции или массивы нулевой длины или "" вместо null.Для классов приложений рассмотрите возможность реализации специального экземпляра, который вы можете использовать вместо null.

. Вторая стратегия заключается в замене использования открытых структур данных (например, карт, списков, массивов) на пользовательские классы.Это скрывает детали реализации внутри класса и позволяет вам использовать статическую типизацию Java, чтобы избежать многих ситуаций, когда потребуется проверка на нуль.

Третья стратегия заключается в создании вспомогательного класса скуча методов, которые реализуют общие операции;например, "получить Cam для LD".(ИМО, этот подход - плохая альтернатива по сравнению с другими, но, по крайней мере, он уменьшает количество повторений кода.)

В той степени, в которой вы не можете избавиться от нулей, у вас нетвариант, но явно проверить их.(Было предложение добавить оператор «elvis» в Java 7 как часть проекта Coin, но, к сожалению, он был сокращен.)

1 голос
/ 11 августа 2010

Проект apache commons имеет библиотеку под названием Bean Introspection Utilities (BeanUtils), которая, похоже, может делать то, что вам нужно.Ознакомьтесь с разделом доступа к вложенным свойствам в руководстве пользователя и посмотрите на класс BeanUtils:

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

У него есть служебные классы, которые, я думаю, могут делать то, что вам нужно.

Еще один момент, на который следует обратить внимание: вам следует избегать такого большого количества уровней доступа к вложенным свойствам.Это запах кода, называемый «завистью к функциям», когда объект хочет регулярно использовать функции другого объекта.Подумайте о создании методов для объекта верхнего уровня или найдите способ перепроектировать, чтобы обеспечить более удобный доступ к нужной функции.

0 голосов
/ 11 августа 2010

Я думаю, что-то более полно, чем нужно, если вам нужно сделать

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

Если вам нужно проверить, является ли вторая коллекция или результат нулевым, вы можете сделать что-то вроде:

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
}

С помощью этого кода я проверил, является ли первая коллекция не нулевой, не пустой и имеет ли она содержимое.Я получаю вторую коллекцию и повторяю процесс во второй коллекции.

Также можно создать метод для выполнения этой операции:

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

и в вашем коде:

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 голосов
/ 11 августа 2010

Код в Groovy!.

Не всегда возможно в зависимости от вашей среды и требований к производительности.Но радостно просто набрать

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

Альтернативно, вы можете просто кодировать то, что вы имеете в виду, и ловить исключение нулевого указателя.В вашем случае это будет гораздо более читабельным, особенно если вам не важно, какой элемент равен нулю.

0 голосов
/ 11 августа 2010
try {
   foo().bar().baz();
} catch (NullPointerException e) {
    // Check if it was actually an error
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...