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

Лучший способ форматировать несколько "или" условий в операторе if (Java)

Простой вопрос, но Google не очень помогает.

У меня есть оператор if со многими условиями (нужно проверить наличие 10 или 15 констант, чтобы увидеть, присутствует ли кто-либо из них.)

Вместо того, чтобы писать что-то вроде:

if (x == 12 || x == 16 || x == 19 || ...)

есть ли способ форматировать его как

if x is [12, 16, 19]?

Просто интересно, есть ли более простой способ закодировать это, любая помощь оценивается.

Изменить. Ответы были очень полезными, но меня попросили добавить несколько деталей, чтобы я сделал это, чтобы насытить их любопытство. Я делал класс проверки даты, который должен был удостовериться, что дни не были > 30 в месяцах, которые имеют только 30 дней (из которых 4, я думаю), и я писал инструкцию if, чтобы проверить такие вещи:

if (day > 30 && (month == 4 || month == 6 || month == 9 || month == 11))

Мне просто интересно, был ли более быстрый способ кодировать такие вещи - многие из приведенных ниже ответов помогли:).

4b9b3361

Ответ 1

Я часто использую этот тип рисунка. Он очень компактный:

// Define a constant in your class. Use a HashSet for performance
private static final Set<Integer> values = new HashSet<Integer>(Arrays.asList(12, 16, 19));

// In your method:
if (values.contains(x)) {
    ...
}

A HashSet используется здесь, чтобы обеспечить хорошую производительность поиска - даже очень большие хэш-множества способны выполнить contains() очень быстро.

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

if (Arrays.asList(12, 16, 19).contains(x))

но знайте, что он будет создавать новый ArrayList каждый раз, когда он выполняется.

Ответ 2

Вы хотите переключиться на это?

switch(x) {
    case 12:
    case 16:
    case 19: 
        //Do something
        break;
    default:
        //Do nothing or something else..
        break;
}

Ответ 3

Нет, вы не можете сделать это на Java. вы можете написать метод следующим образом:

boolean isContains(int i, int ... numbers) {
    // code to check if i is one of the numbers
    for (int n : numbers) {
        if (i == n) return true;
    }
    return false;
}

Ответ 4

Вы можете найти наличие ключа карты или посмотреть, есть ли он в наборе.

В зависимости от того, что вы на самом деле делаете, возможно, вы пытаетесь решить проблему неправильно:)

Ответ 5

Используйте какую-то коллекцию - это сделает код более читаемым и спрячет все эти константы. Простым способом будет со списком:

// Declared with constants
private static List<Integer> myConstants = new ArrayList<Integer>(){{
    add(12);
    add(16);
    add(19);
}};

// Wherever you are checking for presence of the constant
if(myConstants.contains(x)){
    // ETC
}

Как указывает Богемиан, список констант может быть статическим, поэтому он доступен в нескольких местах.

Для всех, кого интересует, в моем примере используется двойная инициализация скобок. Поскольку я столкнулся с этим в последнее время, я нашел приятным для написания быстрых и грязных инициализаций списка.

Ответ 6

Если набор возможностей "компактный" (т.е. наибольшее значение - наименьшее значение, скажем, меньше 200), вы можете рассмотреть таблицу поиска. Это было бы особенно полезно, если бы у вас была такая структура, как

if (x == 12 || x == 16 || x == 19 || ...)
else if (x==34 || x == 55 || ...)
else if (...)

Настройте массив со значениями, идентифицирующими ветвь, которая будет взята (1, 2, 3 в примере выше), а затем ваши тесты станут

switch(dispatchTable[x])
{
    case 1:
        ...
        break;
    case 2:
        ...
        break;
    case 3:
        ...
        break;
}

Независимо от того, подходит ли это, зависит от семантики проблемы.

Если массив не подходит, вы можете использовать Map<Integer,Integer>, или если вы просто хотите проверить членство для одного оператора, это сделает Set<Integer>. Тем не менее, много огневой мощи для простого оператора if, поэтому без какого-либо контекста вам будет трудно вести вас в правильном направлении.

Ответ 7

С Java 8 вы можете использовать примитивный поток:

if (IntStream.of(12, 16, 19).anyMatch(i -> i == x))

но это может иметь небольшие накладные расходы (или нет), в зависимости от количества сравнений.