我想知道如何屏蔽值,以便我可以设置配置。让我知道我有常数 Options.A = 0
,Options.B = 1
等等......
builder.setOption( Option.A & Option.C ); // Or should I use '|' operator?
这意味着
Option.A Option.B Option.C Option.D
1 0 1 0
由于1010
是数字10
的二进制,因此它意味着builder.option = 10;
,但在实际实现中我会有switch
个案例,可以将其比较:
// inside builder.someFunction();
switch(this.option) {
case Option.A & Option.C:
注意:请纠正我,如果这不是你如何使用按位运算符来掩盖值,我已经阅读了很多并且不太了解它,所以如果这是错的我可能需要switch-case
这样的例子。
PS:我从Android
框架中获取了一行代码,如下所示:
view.gravity = Gravity.TOP | Gravity.LEFT;
这是我想要实现的类似行为。
答案 0 :(得分:1)
我从来没有实现过这个,但它发生在我身上:
对于第一个问题,是的,你需要使用| (而不是&)正确地积累选项
如果你要在一个变量中累积选项,那么要检查哪些选项是ON我会使用来:
for(int i=0;i<32;i++){
if(i&options){//check if i-th option is ON
option_function(i);
}
}
并在option_function()内部执行切换案例。
void option_function(int i){
switch(i) {
case Option.A:
....
}
}
答案 1 :(得分:1)
首先,理论:
(1)我们忽略数据类型,假设您有4个选项:
Option.A Option.B Option.C Option.D
然后你需要使用一个4位宽的变量来表示它们。假设Option.A是最高(最左侧)位,Option.D是最低位(最右侧)。然后这个变量看起来:
Option.A Option.B Option.C Option.D
bit3 bit2 bit1 bit0
其范围为0000~1111,代表2 ^ 4 = 16种不同组合。
(2)对于位操作,首先应为每个选项定义掩码:
var Mask.A = 1000;
var Mask.B = 0100;
var Mask.C = 0010;
var Mask.D = 0001;
&lt; 1&gt;如果要表示具有Option.B和Option.C的值,可以使用OR
操作:
var v_B_and_C = Mask.B | Mask.C = 0100 | 0010 = 0110;
&lt; 2&gt;如果要检查某个值是否包含Option.B,请使用AND
,然后比较结果:
var some_v = 1101;
var result = some_v & Mask.B = 1101 & 0100 = 0100;
if(result != 0000) {// Contains Option.B! }
else {// ==0000. Not contains Option.B! }
&lt; 3&gt;如果您想撤销某个值,可以使用NOT
/ XOR
:
var some_v = 0011;
var reversion_v = ~some_v = ~0011 = 1100;
// you can also use XOR(^) between a value and an all-1 constant
var reversion_v = some_v ^ 1111 = 0011 ^ 1111 = 1100;
&lt; 4&gt;如果您想知道两个值之间的差异,可以使用XOR
:
var v_1 = 1100, v_2 = 0110;
var diff = v_1 ^ v_2 = 1100 ^ 0110 = 1010 // Means bit3, bit1 are different!
&lt; 5&gt;对于其他用法,请参考:Bitwise Operation
其次,在Java中练习:
(1)你需要明确的第一件事是你需要代表多少Options(bits)
?
因为不同的数据类型具有不同的宽度(表示不同的范围):
如果您需要超过64个选项,您可能需要使用数组(int [] / long [])或方便的类:java.util.BitSet
(2)如果要通过数组实现自己,请使用按位运算关键字(&amp;,|,^,〜,&lt;&lt;&lt;,&gt;&gt;&gt;)。有一个以二进制格式打印出int的提示:
int i = 0x80000000;
System.out.println(Integer.toBinaryString(i));
// Print: 10000000000000000000000000000000
(3)我建议使用java.util.BitSet
类,除非你有理由必须自己实现。例如:
import java.util.BitSet;
public class Main {
public static void main(String[] args) {
// Create a BitSet object, which can store 128 Options.
BitSet bs = new BitSet(128);
bs.set(0);// equal to bs.set(0,true), set bit0 to 1.
bs.set(64,true); // Set bit64
// Returns the long array used in BitSet
long[] longs = bs.toLongArray();
System.out.println(longs.length); // 2
System.out.println(longs[0]); // 1
System.out.println(longs[1]); // 1
System.out.println(longs[0] ==longs[1]); // true
}
}
其他用法,see the java docs
答案 2 :(得分:0)
为什么不创建一个更易于阅读和使用标准API的类?
public class Permissions {
final BitSet permissions;
public Permissions() {
permissions = new BitSet();
}
public void setPermission(int p) {
permissions.set(p);
}
}