Есть ли более простой способ проверить несколько значений по одному значению в if-statement?
В принципе, я хочу проверить два целых числа против данного значения, поэтому классически, что вы делаете, это примерно так:
//just to get some values to check
int a, b;
a = (int)(Math.random()*5);
b = (int)(Math.random()*5);
//the actual thing in question
if(a == 0 || b == 0)
{
//Then do something
}
Но есть ли более сжатый формат для этого? Возможно, похоже на это (что возвращает неправильный тип операнда):
//just to get some values to check
int a, b;
a = (int)(Math.random()*5);
b = (int)(Math.random()*5);
//the actual thing in question
if((a||b) == 0)
{
//Then do something
}
Ответы
Ответ 1
К сожалению, такой конструкции в Java нет.
Такое сравнение часто встречается в вашем коде, вы можете реализовать небольшую функцию, которая будет выполнять проверку для вас:
public boolean oneOfEquals(int a, int b, int expected) {
return (a == expected) || (b == expected);
}
Затем вы можете использовать его следующим образом:
if(oneOfEquals(a, b, 0)) {
// ...
}
Если вы не хотите ограничивать свой набор целыми числами, вы можете сделать эту функцию общей:
public <T> boolean oneOfEquals(T a, T b, T expected) {
return a.equals(expected) || b.equals(expected);
}
Обратите внимание, что в этом случае среда выполнения Java будет выполнять автоматический бокс и распаковку для примитивных типов (например, int
), что является потерей производительности.
Ответ 2
Вы можете сделать следующее в простой java
Arrays.asList(a, b, c, d).contains(x);
Ответ 3
Я думаю, что бит-мудрый OR:
if ((a | b) == 0) . . .
будет работать, если вы хотите конкретно проверить на 0. Я не уверен, что это экономит время выполнения. Более того, он делает для загадочного кода, который заставит будущего сопровождающего этого кода проклинать вас (даже если он сам). Я рекомендую придерживаться более типичного варианта.
Ба. Я неправильно понял оригинальную логику OP.
Другие идут...
Если вы хотите проверить, равна ли какая-либо из многих переменных ожидаемому значению, может работать общая функция:
public <T> boolean exists(T target, T... values) {
for (T value : values) {
if (target == null) {
if (value == null) {
return true;
}
} else if (target.equals(value)) {
return true;
}
}
return false;
}
Это будет работать для любого количества объектов одного типа. Примитивы будут автобоксами, поэтому они будут работать и с ними. Ваш исходный код будет выглядеть примерно так:
if (test(0, a, b)) {
// do something
}
(Лучшее имя метода было бы отчаянно необходимо, чтобы даже подумать, улучшилось ли это по сравнению с тем, что у вас есть. Даже если тест расширяется до 3 или 4 переменных, я сомневаюсь в необходимости такого рода вещей.) Обратите внимание, что это также работает с массивами:
int[] values = { . . . };
if (test(0, values)) { . . .
и его можно использовать для проверки того, является ли массив (или любой из набора переменных) null
.
Ответ 4
if(a == 0 || b == 0)
{
//Then do something
}
Почему бы не сохранить его читабельным? Что не является кратким в этом вопросе? С другой стороны,
a = (int)(Math.random()*5);
включает ненужный приведение. Почему бы просто не использовать Random
и вызвать nextInt()
?
Ответ 5
В этом примере вы можете сделать
if (a * b == 0)
или для большего количества переменных
if (a * b * c * d == 0)
в то время как более кратким это может быть не так ясно. Для более крупных значений вам нужно указать long
, чтобы избежать переполнения.
Ответ 6
Вы можете поместить целые числа в набор и посмотреть, содержит ли оно заданное значение. Использование Guava:
if(newHashSet(a, b).contains(0)){
// do something
}
Но в этом случае, возможно, проще понять два простых сравнения.
Ответ 7
Здесь приведена модификация ответа @buc, которая может принимать любое количество любых аргументов:
public <T> boolean oneOfEquals(T expected, T... os) {
for (T o : os) {
if (expected.equals(o)) return true;
}
return false;
}
Ответ 8
Даже если вы использовали битовую операцию, предложенную Тедом, выражения не равны, так как требуется не менее одна переменных, а вторая требует обоих из них равны нулю.
Что касается вашего вопроса, в Java нет такого ярлыка.
Ответ 9
Вы можете попробовать этот код:
public static boolean match (Object ref, Object... objects)
{
if (ref == null)
return false;
//
for (Object obj : objects)
if (obj.equals (ref))
return true;
//
return false;
} // match
Итак, если вы можете проверить этот способ:
if (match (reference, "123", "124", "125"))
; // do something
Ответ 10
Как указано в этом ответе:
В Java 8+ вы можете использовать Stream
и anyMatch
. Что-то вроде
if (Stream.of(b, c, d).anyMatch(x -> x.equals(a))) {
// ... do something ...
}
Обратите внимание, что это может привести к более медленному запуску, чем другие, если проверка выполняется из-за накладных расходов на перенос этих элементов в поток для начала.
Ответ 11
Для этого нет специального синтаксиса. Вы можете сделать для этого функцию. Предполагая хотя бы Java 1.5:
public <T> boolean eitherOneEquals(T o1, T o2, T expectedValue) {
return o1.equals(expectedValue) || o2.equals(expectedValue);
}
if(eitherOneEquals(o1, o2, expectedValue)) {
// do something...
}
Ответ 12
В Java 8 мы можем добиться того же, используя метод ниже:
private boolean methodName(int variant,int... args){
if(args.length > 0){ return Arrays.stream(args).anyMatch( x -> x == variant); }
return false;
}
Данный метод вернет true, если вариант будет соответствовать любым возможным входным данным. Это используется для или условия.
Таким же образом, если вы хотите выполнить условие && (и), вам просто нужно использовать другие методы Java 8:
Примечание: эти методы принимают Predicate в качестве аргумента.
anyMatch: возвращает true в тот момент, когда первый предикат возвращает true, в противном случае - false.
allMatch: вернуть true, если все предикаты возвращают true, иначе false.
noneMatch: вернуть true, если ни один из предикатов не вернет true, иначе false.