在Java中将布尔值转换为整数

418

在Java中,将boolean类型转换为int类型的最常用方式是什么?


8
你认为哪些整数分别对应于“true”和“false”? - Thorbjørn Ravn Andersen
6
有些语言有从整数到布尔类型的隐式转换,Java不支持。不过,官方实现包括SQL包,我相信这些包会将“false”转换为0。 - hpique
4
@Peter Lawrey 如果你想与其他没有布尔值作为非数值数据类型的系统进行互操作,那么就不行。 - hpique
7
问题并不是关于值映射的,而是关于如何以最清晰、最被接受的方式进行转换。 - hpique
9
从技术上讲,Java编译器已经定义了一种映射关系。True和False分别被编译为1和0。 - Antimony
显示剩余6条评论
12个回答

705
int myInt = myBoolean ? 1 : 0;

PS: true = 1,false = 0。


63
如果myBoolean代表一个布尔表达式,使用括号更易读。 - rsp
45
是的,就像(foo && (!bar || baz)) ? 1 : 0中的那样。显然,如果它只是一个标识符,那么括号是不必要且不可取的。 - Blrfl
1
对于像我这样的初学者,(boolean expression) ? 1 : 0; 更容易理解。我认为 my 前缀让它看起来像一个变量。 - dixhom
12
在您的示例中,括号是必须的,而不仅仅是为了可读性。foo && (!bar || baz) ? 1 : 0 将会是一个语法错误。(我知道已经过去6年了) - Konrad Morawski
1
优美而优雅 :) - Michał Mirowski
显示剩余5条评论

164
int val = b? 1 : 0;

81

使用三元运算符是实现你想要的任务最简单、最高效、最可读的方式。我鼓励你使用这种解决方案。

然而,我不禁提出一个替代的、牵强附会的、低效难懂的方案。

int boolToInt(Boolean b) {
    return b.compareTo(false);
}

嘿,人们喜欢为这样的很棒的答案投票!

编辑

顺便提一下,我经常看到将布尔值转换为整数的转换,目的只是为了比较这两个值(通常在compareTo方法的实现中)。在这些特定情况下,Boolean#compareTo是正确的选择。

编辑2

Java 7引入了一个新的实用函数,直接使用原始类型,即Boolean#compare(感谢shmosel)。

int boolToInt(boolean b) {
    return Boolean.compare(b, false);
}

2
由于现代JIT(即时编译器)的内联优化,所以并不一定低效。此外,它还记录了为什么要使用b.compareTo,以保证代码的可读性。 - Thorbjørn Ravn Andersen
3
因为我们需要将原始值装箱成对象,所以它可能会变慢。三元运算符方法直接使用原始值而无需转换,因此我认为它更有效率。 - barjak
8
  1. 你可以使用 Boolean.compare() 来避免自动装箱。
  2. Boolean.compareTo() 的文档没有说明它将返回1,只有在“该对象表示true且参数表示false时返回正值”。
- shmosel
3
我刚刚进行了一个测试,将1,000,000个随机布尔值进行转换,这种方法始终比基于三元运算符的方法更快。它能够节省大约10毫秒的时间。 - Mapsy
5
如果您进行微基准测试,建议使用框架确保正确测量。请参阅http://openjdk.java.net/projects/code-tools/jmh/。 - Thorbjørn Ravn Andersen
显示剩余3条评论

53
boolean b = ....; 
int i = -("false".indexOf("" + b));

7
是的。使用其他更高效的方法来实现,这些方法不需要额外的开销。除非您能解释创建字符串对象以仅检查布尔值的值在任何方面都是有效的。 - arkon
9
@b1naryatr0phy,你现在过早地进行微观优化。 - Thorbjørn Ravn Andersen
5
微观优化与此无关,因为这完全取决于上下文。如果我调用一个使用此代码块的方法1000000次以上,那么我可能会创建1000000个以上需要进行垃圾回收的额外对象。我不确定你的工作有多苛刻,但如果我尝试使用类似于这样的东西,我的老板会把我拉到一边并且训斥我。 - arkon
13
@ThorbjørnRavnAndersen 我无法控制我的方法被如何使用或被调用的频率,这正是重点。你为了没有任何实际好处而牺牲了性能和可读性。 - arkon
9
这绝对是有创意的,但我想不到使用这种方法的任何一个优点。它更冗长,而且(我猜)不够高效,但它确实是一种有趣的方法。 - Mike Baxter
显示剩余6条评论

30
import org.apache.commons.lang3.BooleanUtils;
boolean x = true;   
int y= BooleanUtils.toInteger(x);

8
BooleanUtils.toInteger 实现的代码只是 return bool ? 1 : 0; - Solomon Ucko
8
Apache Commons可能很有用,但这太荒谬了。 - Eric Duminil
@EricDuminil 这可以在嵌套(?:)或过长的一行代码中稍微增加可读性。 - Pat Lee
在我看来,xyz.stream().map(BooleanUtils::toInteger)xyz.stream().map(x -> x ? 1 : 0) 更易读。 - bb1950328
@bb1950328:是的,这样更易读,但与Apache Commons无关。您可以直接使用https://dev59.com/x2865IYBdhLWcg3wd-ge#3794521中定义的方法。 - Eric Duminil
不幸的是,这在经验不足的开发人员中很常见,他们会包含一个包含数百个类甚至是传递依赖关系的整个库,只是为了使用一些廉价的实用函数。真是荒谬可笑。 - undefined

28
public int boolToInt(boolean b) {
    return b ? 1 : 0;
}

简单的


19

如果您使用 Apache Commons Lang (我认为很多项目都在使用它),您可以像这样使用:

int myInt = BooleanUtils.toInteger(boolean_expression); 

toInteger 方法如果 boolean_expression 为真返回1,否则返回0。


4
BooleanUtils.toInteger 的实现只是简单地返回 bool ? 1 : 0; - Solomon Ucko

16

那要看情况而定。通常最简单的方法是最好的,因为它易于理解:

if (something) {
    otherThing = 1;
} else {
    otherThing = 0;
}
或者
int otherThing = something ? 1 : 0;

但有时使用枚举而不是布尔标志更为实用。假设存在同步和异步过程:

Process process = Process.SYNCHRONOUS;
System.out.println(process.getCode());
在Java中,枚举可以具有额外的属性和方法:
public enum Process {

    SYNCHRONOUS (0),
    ASYNCHRONOUS (1);

    private int code;
    private Process (int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }
}

6
使用if而不是?:的另一个原因是,您可以在if块中设置断点。 - Thorbjørn Ravn Andersen

8
如果你需要将true -> 1false -> 0进行映射,可以按照以下步骤操作:
boolean b = true;
int i = b ? 1 : 0; // assigns 1 to i.

7
如果您想进行代码混淆,请使用以下方法:
System.out.println( 1 & Boolean.hashCode( true ) >> 1 );  // 1
System.out.println( 1 & Boolean.hashCode( false ) >> 1 ); // 0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接