应用系统有很多码值,码值又经常有多选的功能。我们常见的码值处理方式基本上都是使用逗号分隔:
例如:
1=苹果;
2=橘子;
3=香蕉;
4=荔枝;
5=菠萝;
6=韭菜;
如果同时选择苹果、香蕉、韭菜,那么我们大概率的存储方式为1,3,6,当我们有需要转换码值的时候,只要使用split逗号即可。然而这种字符串操作的效率其实并不高,而且我们无法给出很短的字段去控制长度,比如当全选的时候,我们会获得一个1,2,3,4,5,6这么长的字段。
对于需要频繁传递信息,并且网络资源和存储资源都非常有限的情况下,这里转换一下思维,换个方式解决一下码值多选的问题。
首先引入一个运算,按位与(&);
其实这个运算非常简单,就是数字转换成二进制,然后每位做运算:
1&1=1,1&0=0,0&0=0,0&1=0;其实你只要记住第一个就行了。
那么首先我们来看几个常见的并且有规律的数字转为二进制:
//十进制转二级制
System.out.println(Integer.toBinaryString(1));
System.out.println(Integer.toBinaryString(2));
//1+2
System.out.println(Integer.toBinaryString(3));
System.out.println(Integer.toBinaryString(4));
System.out.println(Integer.toBinaryString(8));
//4+8
System.out.println(Integer.toBinaryString(12));
System.out.println(Integer.toBinaryString(16));
System.out.println(Integer.toBinaryString(32));
System.out.println(Integer.toBinaryString(64));
System.out.println(Integer.toBinaryString(128));
输出结果:
1::::::::::::::1
2::::::::::::::10
3::::::::::::::11 3=1+2
4::::::::::::::100
8::::::::::::::1000
12::::::::::::1100 12=8+4
16::::::::::::10000
32::::::::::::100000
64::::::::::::1000000
128::::::::::10000000
这个结果我们可以发现两个规律:
一、对于2的整数幂的二进制都是1+(幂数-1)个0.
二、对于例如 3=1+2;7=1+2+4;这种数字,用它和2的整数次幂做&,得到的结果一定是二的整数次幂本身。
我们用代码模拟做一个试验:
int a = 29;
for (int i = 0; i < 8; i ++) {
System.out.println("i:"+i+":"+(a & (1 << i)));
}
输出结果:
i:0:1
i:1:0
i:2:4
i:3:8
i:4:16
i:5:0
i:6:0
i:7:0
很容易判断出29=1+4+8+16;
所以当我们设计码值的时候,如果码值本身不多,比如在2^10以内。那么我们最终最多设置一个4位的数字就可以存放码值。而在进行码值翻译的时候,一个是上面方法的位移计算,一个是&运算,其实效率都是非常高的。
PS:注意码值必须是2的整数幂,不适合1 2 3 4 5 这种码值操作。