Лучший способ отформатировать несколько условий 'или' в операторе if (Java) - PullRequest
42 голосов
/ 30 сентября 2011

Простой вопрос, но 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))

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

Ответы [ 7 ]

45 голосов
/ 30 сентября 2011

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

// 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 каждый раз, когда будет выполняться.

10 голосов
/ 30 сентября 2011

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

switch(x) {
    case 12:
    case 16:
    case 19: 
        //Do something
        break;
    default:
        //Do nothing or something else..
        break;
}
3 голосов
/ 30 сентября 2011

Нет, вы не можете сделать это в 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;
}
3 голосов
/ 30 сентября 2011

Если набор возможностей является «компактным» (т. Е. Наибольшее значение - наименьшее значение, скажем, меньше 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, так что без большего контекста сложно направить вас в правильном направлении.

3 голосов
/ 30 сентября 2011

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

// 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
}

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

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

3 голосов
/ 30 сентября 2011

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

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

2 голосов
/ 16 ноября 2016

В Java 8 вы могли бы использовать примитивный поток:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...