- By刘立博
- 2020-03-06 23:46:52
- 908人已阅读
位图并不是什么特殊的数据结构,而是一个字节数组。我们既可以使用get/set向其设置一个普通的ASCII码字符,也可以通过getbit/setbit按比特位设置高位/低位。
设置和读取
按比特位设置高位/低位,并按位读取
假定保存某用户本周的签到情况,该用户星期一,星期二,星期天进行了签到操作:
星期 |
星期一 |
星期二 |
星期三 |
星期四 |
星期五 |
星期六 |
星期天 |
签到情况 |
签到 |
签到 |
未签到 |
未签到 |
未签到 |
未签到 |
签到 |
比特值 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
比特位 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
设置比特值
通过使用setbit,将0,1,6位置为高位:
192.168.3.9:6379> setbit testWeek 0 1
(integer) 0
192.168.3.9:6379> setbit testWeek 1 1
(integer) 0
192.168.3.9:6379> setbit testWeek 6 1
(integer) 0
JAVA实现:
@SpringBootTest
public class TestRedis {
@Autowired
RedisTemplate<String,String> redisTemplate;
@Test
public void testRedis()
{
redisTemplate.opsForValue().setBit("testWeek",0,true);
redisTemplate.opsForValue().setBit("testWeek",1,true);
redisTemplate.opsForValue().setBit("testWeek",6,true);
}
}
PS:为了降低冗余,后续的JAVA代码只包含testRedis方法中的代码
读取比特值
通过getbit,便可以获取该用户每日签到明细:
192.168.3.9:6379> getbit testWeek 0
(integer) 1
192.168.3.9:6379> getbit testWeek 1
(integer) 1
192.168.3.9:6379> getbit testWeek 2
(integer) 0
192.168.3.9:6379> getbit testWeek 3
(integer) 0
192.168.3.9:6379> getbit testWeek 4
(integer) 0
192.168.3.9:6379> getbit testWeek 5
(integer) 0
192.168.3.9:6379> getbit testWeek 6
(integer) 1
JAVA实现:
for (int i = 0; i < 7 ; i++)
System.out.println(i+":"+redisTemplate.opsForValue().getBit("testWeek", i));
输出:0:true,1:true,2:false,3:false,4:false,5:false,6:true
按比特位设置ASCII字符,以字节读取
假定需要把A存放进位图:A的ASCII码为65,转为2进制为:01000001
高位 <- 低位
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
但Redis设置顺序是从低位->高位,所以比特位设置顺序为:
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
所以,将第1位和第7位设置为1,即可:
192.168.3.9:6379> setbit mapA 1 1
(integer) 0
192.168.3.9:6379> setbit mapA 7 1
(integer) 0
192.168.3.9:6379> get mapA
"A"
统计
高位统计
使用bitcount,可以统计出该位图中高位的数量,比如统计签到天数:
192.168.3.9:6379> bitcount testWeek
(integer) 3
JAVA实现:
System.out.println(
redisTemplate.execute(
(RedisCallback<Long>) rcb -> rcb.bitCount("testWeek".getBytes())
)
);
输出:3
高/低位查找
使用bitpos命令,可以查找出第一个高位/低位的位置,例如需要查找第一次未签到的事件发生于星期几:
192.168.3.9:6379> bitpos testWeek 0
(integer) 2
JAVA实现:
System.out.println(
redisTemplate.execute(
(RedisCallback<Long>) rcb -> rcb.bitPos("testWeek".getBytes(),false)
)
);
输出:2