#java #if-statement
Вопрос:
У меня есть оператор if со многими условиями (нужно проверить наличие 10 или 15 констант, чтобы увидеть, присутствуют ли какие-либо из них.)
Вместо того, чтобы писать что-то вроде:
if (x == 12 || x == 16 || x == 19 || ...)
есть ли какой-либо способ отформатировать его следующим образом
if x is [12, 16, 19]?
Просто интересно, есть ли более простой способ закодировать это, любая помощь приветствуется.
Ответы были очень полезными, но несколько человек попросили меня добавить больше деталей, поэтому я сделаю это, чтобы удовлетворить их любопытство. Я создавал класс проверки даты, который должен был убедиться, что дней не было> 30 в месяцах, в которых всего 30 дней (которых, я думаю, 4), и я писал оператор if, чтобы проверить такие вещи:
if (day > 30 amp;amp; (month == 4 || month == 6 || month == 9 || month == 11))
Мне просто было интересно, есть ли более быстрый способ кодирования подобных вещей — многие из приведенных ниже ответов помогли.
Комментарии:
1. Можете ли вы привести лучший пример того, что вы пытаетесь сделать? Может быть, решение заключается в том, чтобы подумать об этом?
Ответ №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
при каждом выполнении он будет создавать новое.
Комментарии:
1. if (Arrays.asList(12, 16, 19).содержит (x))
2. Я бы предпочел использовать
Set
List
для этого a, а не a, но это не окажет никакого влияния на эти несколько элементов.3. @Joachim Sauer включил вашу идею — она тоже хороша! HashSet будет намного быстрее
4. Использование Guava :
private static final ImmutableSet<Integer> values = ImmutableSet.of(12, 16, 19);
Ответ №2:
Вы хотите переключиться на это??
switch(x) {
case 12:
case 16:
case 19:
//Do something
break;
default:
//Do nothing or something else..
break;
}
Ответ №3:
Если набор возможностей является «компактным» (т. Е. Наибольшее значение наименьшего значения, скажем, меньше 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;
}
Подходит это или нет, зависит от семантики проблемы.
Если массив не подходит, вы можете использовать a Map<Integer,Integer>
, или, если вы просто хотите проверить членство в одном операторе, подойдет a Set<Integer>
. Однако для простого оператора это большая огневая if
мощь, поэтому без дополнительного контекста довольно сложно направить вас в правильном направлении.
Ответ №4:
Используйте какую-нибудь коллекцию — это сделает код более читаемым и скроет все эти константы. Простой способ — использовать список:
// 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
}
Как указывает Богемиан, список констант может быть статическим, поэтому он доступен более чем в одном месте.
Для всех, кому интересно, список в моем примере использует инициализацию с двойными фигурными скобками. С тех пор как я столкнулся с этим недавно, я нашел его удобным для написания быстрых и грязных инициализаций списка.
Комментарии:
1. или
if(Arrays.asList(new int[]{12,16,19}).contains(x)){ ... }
2. @Bala конечно! В любом случае список — это всего лишь пример используемой здесь коллекции. Как было предложено в одном из других ответов, set может быть лучше, чтобы гарантировать, что константы уникальны… Или хеш-таблица для ускорения поиска и т. Д.
Ответ №5:
Вы можете проверить наличие ключа map или посмотреть, есть ли он в наборе.
Однако, в зависимости от того, что вы на самом деле делаете, вы можете пытаться решить проблему неправильно 🙂
Ответ №6:
Нет, вы не можете сделать это на 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;
}
Ответ №7:
В Java 8 вы можете использовать примитивный поток:
if (IntStream.of(12, 16, 19).anyMatch(i -> i == x))
но это может иметь небольшие накладные расходы (или нет), в зависимости от количества сравнений.