简述
项目中需要标记一个商品多种状态改变,比如商品价格改变,库存改变,状态改变等,只要其中一个改变,就要进行更新商品在缓存中的规则。如果按照普通做法,使用多个boolean类型来标识每个状态改变,也是行的通,不过浪费内存。我们最终使用了位运算来标识开关状态。
实现
Java int类型32位,我们可以把每一位当成一个开关。所以最大支持32个开关。当为1的时候,代表打开开关;如果为0,则代表关闭开关
代码
/**
* 用位存储开关状态,可以支持最多32个开关。
*
* @author Terry
*/
public class BitConfigUtils {
/**
* 是否已打开某个开关
*
* @param configType
* @return
*/
public final static boolean isOn(int config, int configType) {
return (config & (0x1 << configType)) != 0;
}
/**
* 打开某个开关
*
* @param configType
*/
public final static int on(int config, int configType) {
return config | (1 << configType);
}
/**
* 打开某些开关
*
* @param configTypes
*/
public final static int on(int config, int... configTypes) {
for (int configType : configTypes) {
config |= (1 << configType);
}
return config;
}
/**
* 关闭某个开关
*
* @param configType
*/
public final static int off(int config, int configType) {
if (isOn(config, configType)) {
return config ^ (1 << configType);
}
return config;
}
/**
* 是否已打开某个开关
*
* @param configType
* @return
*/
public final static boolean isOn(long config, int configType) {
return (config & (0x1 << configType)) != 0;
}
/**
* 打开某个开关
*
* @param configType
*/
public final static long on(long config, int configType) {
return config | (1 << configType);
}
/**
* 打开某些开关
*
* @param configTypes
*/
public final static long on(long config, int... configTypes) {
for (int configType : configTypes) {
config |= (1 << configType);
}
return config;
}
/**
* 关闭某个开关
*
* @param configType
*/
public final static long off(long config, int configType) {
if (isOn(config, configType)) {
return config ^ (1 << configType);
}
return config;
}
}
总结
合理使用位运算,可以大大降低内存使用,这是优势;缺点就是位运算后,我们无法直接可以看出是哪个值变换了,不能直观看出,不过可以使用
isOn
方法,来判断哪个开关已经打开。
评论区