Redis从2.2.0版本开始新增了setbit
,getbit
,bitcount
等几个bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型。redis 通过对bitmap 来实现对二进制bit位的操作,用来记录一些状态信息。其中一个字节占8个bit位。用bit位中的二进制的0 和1 各表示一个状态,以达到记录某些状态信息。因为所有的状态都是记录基于二进制的bit位。所以大大的节省了这些状态的占用空间。
语法请参考redis文档。
jedis 对redis bitmap设置操作信息如下:
public String tesetBitMap(@PathVariable String key){
jimClient.setBit("bitmattest",0,true);//将bit位的第0个位置设置为1
jimClient.setBit("bitmattest",1,true);
jimClient.setBit("bitmattest",2,true);
jimClient.setBit("bitmattest",3,true);
jimClient.setBit("bitmattest",4,false);
jimClient.setBit("bitmattest",5,false);
jimClient.setBit("bitmattest",6,true);
jimClient.setBit("bitmattest",7,true);//将bit位的第7个位置设置为1 注意 0 - 7 这里是第一个字节
jimClient.setBit("bitmattest",8,true);//8是第二个字节的第一个bit位 15 是第二个自己的最后一个bit位
jimClient.setBit("bitmattest",9,true);
jimClient.setBit("bitmattest",10,false);
jimClient.setBit("bitmattest",11,false);
jimClient.setBit("bitmattest",17,true);
jimClient.setBit("bitmattest",20,true);
jimClient.setBit("bitmattest",23,true);
jimClient.setBit("bitmattest",24,true);
jimClient.setBit("bitmattest",26,false);
long a = jimClient.bitCount("bitmattest");//统计所有比特位为1的总数
long b11 = jimClient.bitCount("bitmattest",0L,0L);//统计第1个字节(第0 位到第7位)中的为1的总数
long b12 = jimClient.bitCount("bitmattest",0L,1L);//统计前两个字节(第0 位到第15位)中的为1的总数
long b123 = jimClient.bitCount("bitmattest",2L,5L);//统计第个二个字节到第五个字节(第16 位到第39位)中的为1的总数
boolean a0 = jimClient.getBit("bitmattest",0);
boolean a1 = jimClient.getBit("bitmattest",1);
boolean a2 = jimClient.getBit("bitmattest",2);
boolean a3 = jimClient.getBit("bitmattest",3);
boolean a4 = jimClient.getBit("bitmattest",4);
boolean a5 = jimClient.getBit("bitmattest",5);
boolean a6 = jimClient.getBit("bitmattest",6);
boolean a7 = jimClient.getBit("bitmattest",7);
boolean a8 = jimClient.getBit("bitmattest",8);
boolean a9 = jimClient.getBit("bitmattest",9);
boolean a10 = jimClient.getBit("bitmattest",10);
byte[] aaa = jimClient.get("bitmattest".getBytes());//取出这个bitmap
// String bbb = new String(aaa);
BitSet set = PromotionUserBitSetHelper.byteArray2BitSet(aaa); //转成java中的BitSet BitSet的操作请参看Java api
boolean b0 = set.get(0);
boolean b1 = set.get(1);
boolean b2 = set.get(2);
boolean b3 = set.get(3);
boolean b4 = set.get(4);
boolean b5 = set.get(5);
boolean b6 = set.get(6);
boolean b7 = set.get(7);
boolean b8 = set.get(8);
boolean b9 = set.get(9);
boolean b10 = set.get(10);
System.out.println("a0=" + a0 + " ");
System.out.println("a1=" + a1 + " ");
System.out.println("a2=" + a2 + " ");
System.out.println("a3=" + a3 + " ");
System.out.println("a4=" + a4 + " ");
System.out.println("a5=" + a5 + " ");
System.out.println("a6=" + a6 + " ");
System.out.println("a7=" + a7 + " ");
System.out.println("a8=" + a8 + " ");
System.out.println("a9=" + a9 + " ");
System.out.println("a10=" + a10 + " ");
System.out.println("共有多少个true:" + a);
System.out.println("b0=" + b0);
System.out.println("b1=" + b1);
System.out.println("b2=" + b2);
System.out.println("b3=" + b3);
System.out.println("b4=" + b4);
System.out.println("b5=" + b5);
System.out.println("b6=" + b6);
System.out.println("b7=" + b7);
System.out.println("b8=" + b8);
System.out.println("b9=" + b9);
System.out.println("b10=" + b10);
return "123";
}
Java 中的 byte 和BitSet 的个各种转换工具类:
public class PromotionUserBitSetHelper {
static final String BIN_PREFIX = "01";
/**
* bitset offset计算
* 第一位为是否为京东老用户 index=0
* 第二位为是否参与过拼团
* 第三位为是否发起过拼团
* 第四位为是否参与过抽奖拼团
* 第五位为是否发起过抽奖拼团
* 依次类推按照actType 定义
* 从小到大排序
*
*/
public static Integer calculateOffset(PromotionNewUser pnu ){
return pnu.getFirstActType()*2-pnu.getFirstActRole();
}
public static Integer calculateOffset(FirstUserPromotionDTO dto ){
return dto.getActType()*2-dto.getActRole();
}
public static BitSet byteArray2BitSet(byte[] bytes) {
BitSet bitSet = new BitSet(bytes.length * 8);
int index = 0;
for (int i = 0; i < bytes.length; i++) {
for (int j = 7; j >= 0; j--) {
bitSet.set(index++, (bytes[i] & (1 << j)) >> j == 1 ? true
: false);
}
}
return bitSet;
}
public static String binary(byte[] bytes, int radix) {
return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
}
public static byte[] bitSet2ByteArray(BitSet bitSet,int maxSize) {
byte[] bytes = new byte[maxSize];
for (int i = 0; i < maxSize * 8; i++) {
int index = i / 8;
int offset = 7 - i % 8;
bytes[index] |= (bitSet.get(i) ? 1 : 0) << offset;
}
return bytes;
}
public static String toBinaryString(BitSet bitset,int maxSize){
if(bitset == null){
return "0";
}
StringBuilder sb = new StringBuilder(maxSize * 8);
for (int i = 1; i < maxSize * 8; i++) {
sb.append(bitset.get(i)?1:0);
}
return sb.toString();
}
public static String bitSet2BinString(BitSet bitset){
if(bitset == null){
return BIN_PREFIX+"0";
}
return BIN_PREFIX + PromotionUserBitSetHelper.toBinaryString(bitset,UserActConstant.MAX_BYTE_ARRAY_SIZE);
}
public static BitSet binaryToBitSet(String binString){
if(StringUtils.isBlank(binString)){
return null;
}
if (binString.startsWith(BIN_PREFIX)) {
int size = UserActConstant.MAX_BYTE_ARRAY_SIZE * 8;
BitSet bs = new BitSet(size);
binString = binString.substring(BIN_PREFIX.length());
for(int i = 0;i< size && i< binString.length(); i++){
if(binString.charAt(i) == '1'){
bs.set(i);
}
}
}
return null;
}
}