Преобразование Boolean в Integer в Java без If-Statement
Мне интересно, есть ли способ конвертировать логическое значение в int без использования операторов if (чтобы не разрывать конвейер). Например, я мог написать
int boolToInt( boolean b ){
if ( b )
return 1
return 0
Но мне интересно, есть ли способ сделать это без инструкции if, например Python
bool = True
num = 1 * ( bool )
Я также думаю, что вы могли бы сделать
boolean bool = True;
int myint = Boolean.valueOf( bool ).compareTo( false );
Это создает дополнительный объект, однако, поэтому он действительно расточительный, и я нашел его еще медленнее, чем способ if-statement (который не обязательно неэффективен, просто имеет одну слабость).
Ответы
Ответ 1
Вы не можете использовать логическое значение, отличное от if. Однако это не означает, что на уровне сборки будет ветвь.
Если вы проверяете скомпилированный код этого метода (кстати, используя return b ? 1 : 0;
для компиляции с теми же инструкциями), вы увидите, что он не использует скачок:
0x0000000002672580: sub $0x18,%rsp
0x0000000002672587: mov %rbp,0x10(%rsp) ;*synchronization entry
0x000000000267258c: mov %edx,%eax
0x000000000267258e: add $0x10,%rsp
0x0000000002672592: pop %rbp
0x0000000002672593: test %eax,-0x2542599(%rip) # 0x0000000000130000
; {poll_return}
0x00000000025b2599: retq
Примечание: это сервер hotspot 7 - вы можете получать разные результаты на другой виртуальной машине.
Ответ 2
Используйте оператор?: ( b ? 1 : 0 )
Ответ 3
Вы можете использовать тернарный оператор:
return b ? 1 : 0;
Если это считается "если", и учитывая, что это "головоломка", вы можете использовать такую карту:
return new HashMap<Boolean, Integer>() {{
put(true, 1);
put(false, 0);
}}.get(b);
Хотя теоретически реализация HashMap не требует использования if, на самом деле это делает. Тем не менее, "if" не находится в вашем коде.
Конечно, для повышения производительности вы бы:
private static Map<Boolean, Integer> map = new HashMap<Boolean, Integer>() {{
put(true, 1);
put(false, 0);
}};
Тогда в методе:
return map.get(b);
Ответ 4
В противном случае вы можете использовать метод Apache Commons BooleanUtils.toInteger, который работает как прелесть...
// Converts a boolean to an int specifying the conversion values.
static int toInteger(boolean bool, int trueValue, int falseValue)
// Converts a Boolean to an int specifying the conversion values.
static int toInteger(Boolean bool, int trueValue, int falseValue, int nullValue)
Ответ 5
Я нашел решение по структуре. Используйте сравнение для Boolean.
// b = Your boolean result
// v will be 1 if b equals true, otherwise 0
int v = Boolean.compare(b, false);
Ответ 6
Это невозможно напрямую, но не в Java. Вы можете напрямую рассмотреть int
или byte
вместо boolean
, если вам действительно нужно избегать ветки.
Также возможно, что виртуальная машина достаточно умна, чтобы исключить ветвь (if
или ?:
) сама в этом случае, так как внутреннее представление boolean
вполне вероятно будет буквальным 1 или 0 в любом случае. Вот статья о том, как исследовать сгенерированный собственный машинный код для Oracle JDK, и если вам нужна скорость, убедитесь, что вы используете "сервер" JVM поскольку он выполняет более агрессивную оптимизацию, чем "клиентский".
Ответ 7
Я не могу сказать, что рекомендую это. Он как медленнее, чем троичный оператор сам по себе, и он слишком умный, чтобы называться хорошим программированием, но вот это:
-Boolean.FALSE.compareTo(value)
Он использует тернар под обложками (несколько вызовов метода позже), но это не в вашем коде. Справедливости ради, я был бы готов поспорить, что там есть какая-то ветвь в исполнении Python (хотя я, вероятно, делаю ставку только на никель;)).
Ответ 8
Вы можете попробовать использовать тернарный оператор следующим образом
int value = (flag==true ? 1 : 0);
Ответ 9
Поскольку вы не хотите, чтобы решение if/else ваше выражение было совершенным, хотя я бы слегка его изменил
int myint = Boolean.valueOf( bool ).compareTo( Boolean.FALSE );
Нет создания объекта, Boolean.valueOf(boolean b) возвращает либо Boolean.TRUE, либо Boolean.FALSE, см. API
Ответ 10
Разумная альтернатива исчислению троичности, чтобы избежать "if":
private static Boolean[] array = {false, true};
int boolToInt( boolean b ){
return Arrays.binarySearch(array, b);
}
Обратите внимание, что я рассматриваю этот вопрос с "головоломкой", поэтому, если я сам его кодирую, я бы использовал тройную версию.