Как проверить несколько объектов на недействительность?
Часто я вижу кодовые конструкции, подобные следующим:
if(a == null || b == null || c == null){
//...
}
Интересно, есть ли какая-либо широко используемая библиотека (Google, Apache и т.д.) Для проверки на недействительность нескольких объектов одновременно, например:
if(anyIsNull(a, b, c)){
//...
}
или же
if(allAreNulls(a, b, c)){
//...
}
ОБНОВИТЬ:
- Я прекрасно знаю, как написать это сам
- Я знаю, что это может быть результатом плохой структуры программы, но это не так здесь
-
Давайте сделаем это более сложным и заменим оригинальный пример чем-то вроде этого:
if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
//...
}
ОБНОВЛЕНИЕ 2:
Я создал запрос на извлечение библиотеки Apache Commons Lang, чтобы устранить этот пробел:
Они будут включены в commons-lang, версия 3.5:
-
anyNotNull (Object... values)
-
allNotNull (Object... values)
Ответы
Ответ 1
РЕДАКТИРОВАТЬ 2018: Начиная с Apache Commons lang 3.5, были ObjectUtils.allNotNull()
и ObjectUtils.anyNotNull()
.
Нет.
Ни один из Apache Commons Lang (3.4), Google Guava (18) и Spring (4.1.7) не предоставляют такой полезный метод.
Вам нужно будет написать это самостоятельно, если вам это действительно нужно. В современном Java-коде я бы, вероятно, подумал, что такая конструкция должна пахнуть кодом.
Ответ 2
В Java 8 вы можете использовать Stream.allMatch
чтобы проверить, соответствуют ли все значения определенному условию, например, быть null
. Не намного короче, но, возможно, немного легче для чтения.
if (Stream.of(a, b, c).allMatch(x -> x == null)) {
...
}
И, как ни странно, для anyMatch
и ни noneMatch
.
О вашем "более сложном примере": в этом случае я думаю, что нет никакого способа написать лениво оцененное соединение нулевых проверок, подобное тому, которое у вас есть:
if (a != null && a.getFoo() != null && a.getFoo().getBar() != null) {
...
}
Любой другой подход, использующий потоки, списки или методы var-arg, будет пытаться оценить a.getFoo()
до того, как a
будет проверено, чтобы не быть null
. Вы можете использовать Optional
с указателями map
и методов, которые будут лениво оцениваться один за другим, но вопрос о том, делает ли это его более читабельным, является дискуссионным и может варьироваться от случая к случаю (особенно для более длинных имен классов):
if (Optional.ofNullable(a).map(A::getFoo).map(B::getBar).isPresent()) {
...
}
Bar bar = Optional.ofNullable(a).map(A::getFoo).map(B::getBar).orElse(null);
Другой альтернативой может быть try
получить доступ к самому внутреннему предмету, но у меня есть ощущение, что это тоже не считается хорошей практикой:
try {
Bar bar = a.getFoo().getBar();
...
catch (NullPointerException e) {
...
}
В частности, это также поймает любые другие NPE после доступа к этому элементу - либо к этому, либо вы должны поместить только Bar bar =...
в try
и все остальное в другой блок if
после try
, аннулируя любой (сомнительный) выигрыш в читаемости или краткости.
(Я смутно помню что-то о нотации типа a?.getFoo()?.getBar() != null
, но не могу вспомнить, был ли это запрос функции для Java или какой-то совершенно другой язык.)
Ответ 3
Вы также можете использовать что-то вроде следующего метода. Он позволяет передавать столько параметров, сколько вы хотите:
public static boolean isAnyObjectNull(Object... objects) {
for (Object o: objects) {
if (o == null) {
return true;
}
}
return false;
}
Вы вызываете его с таким количеством параметров, которое вам нравится:
isAnyObjectNull(a, b, c, d, e, f);
Вы можете сделать что-то подобное для areAllNull
.
public static boolean areAllObjectsNull(Object... objects) {
for (Object o: objects) {
if (o != null) {
return false;
}
}
return true;
}
Примечание: вы также можете использовать тернарный оператор вместо if (o == null)
. Два метода, показанные здесь, не имеют обработки ошибок. Отрегулируйте его по вашим потребностям.
Ответ 4
Это возможно с помощью класса Objects
public static void requireNonNull(Object... objects) {
for (Object object : objects) {
Objects.requireNonNull(object);
}
}
Ответ 5
Вы можете создать список объектов и использовать в нем yourList.contains(null)
.
List < Object > obList = new ArrayList < Object > ();
String a = null;
Integer b = 2;
Character c = '9';
obList.add(a);
obList.add(b);
obList.add(c);
System.out.println("List is " + obList);
if (obList.contains(null)) {
System.out.println("contains null");
} else {
System.out.println("does not contains null");
}
DEMO
Ответ 6
if (a == null || b == null || c == null || d == null || e == null || f == null)
можно заменить на
if (Arrays.asList(a, b...).contains(null))
if (a != null || b != null || c != null || d != null || e != null || f != null)
можно заменить на
if (Arrays.asList(a, b...).stream().anyMatch(e -> e != null)))
if (a != null && b != null && c != null && d != null && e != null && f != null)
можно заменить на
if (Arrays.asList(a, b...).stream().allMatch(e -> e != null))