web-dev-qa-db-ja.com

Java If-Statementsなしでのブール値から整数への変換

Ifステートメントを使用せずに(パイプラインを中断しないように)ブール値をintに変換する方法があるかどうか疑問に思っています。たとえば、私は書くことができます

int boolToInt( boolean b ){
  if ( b )
    return 1
  return 0

しかし、Pythonのようにifステートメントなしでそれを行う方法があるかどうか疑問に思っています

bool = True 
num = 1 * ( bool )

私もあなたができると思います

boolean bool = True;
int myint = Boolean.valueOf( bool ).compareTo( false );

ただし、これにより余分なオブジェクトが作成されるため、非常に無駄が多く、ifステートメントの方法よりもさらに遅いことがわかりました(必ずしも非効率ではなく、ただ1つの弱点があります)。

19
en_Knight

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  

注:これはホットスポットサーバー7上にあります。異なるVMで異なる結果が得られる場合があります。

26
assylias

?:演算子を使用します:( b ? 1 : 0 )

12
Shadow Man

三項演算子 を使用できます。

return b ? 1 : 0;

これが「if」と見なされ、これが「パズル」である場合、次のようなマップを使用できます。

return new HashMap<Boolean, Integer>() {{
    put(true, 1);
    put(false, 0);
}}.get(b);

理論的には、HashMapの実装ではifを使用する必要はありませんが、実際には使用します。それでも、「if」はyourコードには含まれていません。

もちろん、パフォーマンスを改善するには、次のようにします。

private static Map<Boolean, Integer> map = new HashMap<Boolean, Integer>() {{
    put(true, 1);
    put(false, 0);
}};

次に、メソッドで:

return map.get(b);
4
Bohemian

そうでなければ、チャームのように動作する 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)
4
Romain VDK

フレームワークによる解決策を見つけました。ブール値の比較を使用します。

// b = Your boolean result
// v will be 1 if b equals true, otherwise 0
int v = Boolean.compare(b, false);
2
Björn Frohberg

これをお勧めすることはできません。両方とも三項演算子よりも遅く、優れたプログラミングと呼ぶにはあまりにも賢いですが、これがあります:

-Boolean.FALSE.compareTo(value)

カバーの下の3項を使用します(後でいくつかのメソッド呼び出し)が、コードには含まれていません。公平を期すために、Python実行も同様に(おそらくニッケルのみを賭けます;))のどこかに分岐があることを賭けたいと思います。).

1
Tim Pote

これは、Javaではありません。直接ではありません。とにかく。intの代わりにbyteまたはbooleanを直接使用することを検討できます。本当に分岐を避ける必要があります。

また、VMは、ブランチ(ifまたは?:)それ自体、この場合、booleanの内部表現はリテラル1または0である可能性が高いためです。 記事はこちら Oracle JDK用に生成されたネイティブマシンコードを調べる方法、および速度が必要な場合は、「サーバー」JVMを使用していることを確認してください パフォーマンスが向上するにつれて積極的な最適化 「クライアント」よりも。

1
Boann

「if」を回避するために3項に使用する合理的な代替策:

private static Boolean[] array = {false, true};

int boolToInt( boolean b ){
    return Arrays.binarySearch(array, b);
}

私はこの「パズル」の質問を考慮するので、自分でコーディングする場合は3項を使用することに注意してください。

0
Bohemian

このような三項演算子を使用して試すことができます

int value = flag ? 1 : 0;
0
agpt
int ansInt = givenBoolean ? 1 : 0;
0
Hemant Dhanuka

If/else解決策は必要ないので、あなたの表現は完璧ですが、私はそれを少し変更します

int myint = Boolean.valueOf( bool ).compareTo( Boolean.FALSE );

関係するオブジェクトの作成はありません。Boolean.valueOf(boolean b)はBoolean.TRUEまたはBoolean.FALSEを返します。APIを参照してください

0