簡體   English   中英

在沒有If語句的Java中將布爾值轉換為整數

[英]Converting Boolean to Integer in Java without If-Statements

我想知道是否有一種方法可以將布爾值轉換為 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 語句方式還要慢(這不一定效率低下,只是有一個弱點)。

除了 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 上得到不同的結果。

使用 ?: 運算符: ( b ? 1 : 0 )

您可以使用三元運算符

return b ? 1 : 0;

如果這被認為是一個“如果”,並且考慮到這是一個“謎題”,那么您可以使用這樣的地圖:

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

雖然理論上 HashMap 的實現不需要使用 if,但實際上確實需要。 盡管如此,“如果”不在您的代碼中。

當然,要提高性能,您將:

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

然后在方法中:

return map.get(b);

否則,您可以使用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)

我通過框架找到了解決方案。 對布爾值使用比較。

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

這不是直接可能的,無論如何在 Java 中都不可能。 如果您確實需要避免分支,您可以考慮直接使用intbyte而不是boolean

在這種情況下,VM 也有可能足夠智能以消除分支( if?: )本身,因為boolean的內部表示很可能無論如何都是文字 1 或 0。 這是一篇關於如何檢查為 Oracle JDK 生成的本地機器代碼的文章,如果您需要速度,請確保您使用的是“服務器”JVM, 因為它比“客戶端” 執行更積極的優化

我不能說我推薦這個。 它本身比三元運算符慢,而且它太聰明了,不能稱為好的編程,但是有這個:

-Boolean.FALSE.compareTo(value)

它在幕后使用三元(稍后調用幾個方法),但它不在您的代碼中。 公平地說,我願意打賭 Python 執行中的某個地方也有一個分支(盡管我可能只打賭 ;) )。

您可以嘗試使用這樣的三元運算符

int value = flag ? 1 : 0;

既然你不想要 if / else 解決方案,你的表達是完美的,盡管我會稍微改變它

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

不涉及對象創建,Boolean.valueOf(boolean b) 返回 Boolean.TRUE 或 Boolean.FALSE,參見 API

一個合理的替代 ising 到三元以避免“if”:

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

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

請注意,我認為這是一個“難題”問題,因此如果自己編碼,我將使用三元..

如今,jdk 已經提供了一個有用的 Utils 方法: BooleanUtils.toInteger()

源碼中jdk實現的方法一定是高效的:

public static int toInteger(boolean bool) {
    return bool ? 1 : 0;
}

所以,我認為得票最多的答案非常好, return bool ? 1 : 0 return bool ? 1 : 0是最佳做法。

使用BooleanUtils示例代碼如下:

BooleanUtils.toInteger(false);
int ansInt = givenBoolean ? 1 : 0;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM