Подтвердить что ты не робот

Как проверить несколько объектов на недействительность?

Часто я вижу кодовые конструкции, подобные следующим:

if(a == null || b == null || c == null){
    //...
}

Интересно, есть ли какая-либо широко используемая библиотека (Google, Apache и т.д.) Для проверки на недействительность нескольких объектов одновременно, например:

if(anyIsNull(a, b, c)){
    //...
}

или же

if(allAreNulls(a, b, c)){
    //...
}

ОБНОВИТЬ:

  1. Я прекрасно знаю, как написать это сам
  2. Я знаю, что это может быть результатом плохой структуры программы, но это не так здесь
  3. Давайте сделаем это более сложным и заменим оригинальный пример чем-то вроде этого:

    if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
        //...
    }
    

ОБНОВЛЕНИЕ 2:

Я создал запрос на извлечение библиотеки Apache Commons Lang, чтобы устранить этот пробел:

Они будут включены в commons-lang, версия 3.5:

  • anyNotNull (Object... values)
  • allNotNull (Object... values)
4b9b3361

Ответ 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))