今天仔细了解了下温少的fastjson源码,发现真的是当之无愧的java中最快的json解析库!也发现了一种有趣的算法(当然fastjson中还有TheadLocal缓存、对象路径化、解决互相引用死循环等值得我们深入学习),在fastjson中应用场景是配置序列化json和解析json的可变配置中,他只用了两个int变量来配置(通常我会用List或者Map),先看我模仿他的实现代码先(最后会简要说明),我应用的场景是:高中考试的多选题
实现枚举
package here.wait.go.test.choosed;
/**
* 多选枚举
*
* @author Wait
* @date 2013年12月20日
* @time 下午10:40:22
* @email here.wait.go@gmail.com
* @version 1.0
*/
public enum MultipleChoiceEnum
{
A, B, C, D;
private final int mask;
private MultipleChoiceEnum()
{
mask = 1<<ordinal();
}
public final int getMask()
{
return mask;
}
/**
* 判断是否已经选择
*
* @param multipleChoices
* @param multipleChoiceEnum
* @return
*/
public static boolean isChoosed(int multipleChoices, MultipleChoiceEnum multipleChoiceEnum)
{
return 0 != (multipleChoices & multipleChoiceEnum.getMask());
}
}
测试类
package here.wait.go.test.choosed;
import org.junit.Assert;
import org.junit.Test;
/**
* 模拟多选情况
*
* 选择了A
* multipleChoice |= MultipleChoiceEnum.A.getMask();
*
* 取消选择A
* multipleChoice &= ~MultipleChoiceEnum.A.getMask();
*
* @author Wait
* @date 2013年12月20日
* @time 下午10:48:33
* @email here.wait.go@gmail.com
* @version 1.0
*/
public class MultipleChoiceTest
{
@Test
public void test()
{
int multipleChoices = 0;
//选择了A
multipleChoices |= MultipleChoiceEnum.A.getMask();
//选择了B
multipleChoices |= MultipleChoiceEnum.B.getMask();
//选择C
multipleChoices |= MultipleChoiceEnum.C.getMask();
//突然看同桌不爽,把已选的C去掉
multipleChoices &= ~MultipleChoiceEnum.C.getMask();
Assert.assertEquals(true, MultipleChoiceEnum.isChoosed(multipleChoices, MultipleChoiceEnum.A));
Assert.assertEquals(true, MultipleChoiceEnum.isChoosed(multipleChoices, MultipleChoiceEnum.B));
Assert.assertEquals(false, MultipleChoiceEnum.isChoosed(multipleChoices, MultipleChoiceEnum.C));
Assert.assertEquals(false, MultipleChoiceEnum.isChoosed(multipleChoices, MultipleChoiceEnum.D));
}
}
说明
如上场景有A、B、C、D四个选项
调用方法 式子 二进制
A.getMark() 1<<0 1
B.getMark() 1<<1 10
C.getMark() 1<<2 100
D.getMark() 1<<3 1000
选上是用运算符|(
(有1就1)运算规则:参与运算的二进制数字,低位对齐,高位不足的补零,对应的二进制位有一个为1则结果为1,否则为0。
)
全部选上是1111,所以每个选项占一位
去掉选项是&=~(
&
位与运算符(
都1才1
)运算规则:参与运算的二进制数字,低位对齐,高位不足的补零,对应的二进制位,都是1的为1,否则为0。
)
例如去掉B选项:1111&=~10->1111&=1101->1101
最后怎么知道那个选项被选上了,考试要改试卷了!
正确答案是A、C、D
程序怎么判断呢?是这样的
1101&1(A) !=0 -> true
1101&100(C)!=0 -> true
1101&1000(D)!=0 -> true
恭喜全对了!
优越性
1、比List或者Array的穷举效率要高
2、比使用Map的查表方式更省内存空间
局限性
1、因为是使用二进制的,所以int类型最多只能有32个选项;
2、代码可读性低