黑马点评10——用户签到-BitMap数据结构

BitMap用法

其实数据库完全可以实现签到功能
在这里插入图片描述
但签到数据比较大,借鉴签到卡的思想
在这里插入图片描述
布隆过滤器也是使用BitMap实现的.
在这里插入图片描述

签到功能

在这里插入图片描述
因为是当前用户的当天,所以保存需要的年月日不需要参数,可以直接获取。
在这里插入图片描述

 @Override
    public Result sign() {
        // 1. 获取当前登录用户
        Long userId = UserHolder.getUser().getId();
        // 2. 获取日期
        LocalDateTime now = LocalDateTime.now();
        // 3. 拼接Key
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = USER_SIGN_KEY + userId + keySuffix;
        // 4. 获取今天是本月的第几天
        int dayOfMonth = now.getDayOfMonth();
        // 5. 写入redis SETBIT key offset 1
        stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
        return Result.ok();
    }

签到统计

在这里插入图片描述
在这里插入图片描述

    @Override
    public Result signCount() {
        // 1. 获取当前登录用户
        Long userId = UserHolder.getUser().getId();
        // 2. 获取日期
        LocalDateTime now = LocalDateTime.now();
        // 3. 拼接Key
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = USER_SIGN_KEY + userId + keySuffix;
        // 4. 获取今天是本月的第几天
        int dayOfMonth = now.getDayOfMonth();
        // 5. 获取本月截至今天为止所有的签到记录, 返回一个十进制数字
        List<Long> result = stringRedisTemplate.opsForValue().bitField(
                key,
                BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0)
        );
        if(result == null || result.isEmpty()){
            return Result.ok();
        }
        Long num = result.get(0);
        if(num == null || num == 0){
            return Result.ok();
        }
        // 6. 循环遍历,统计1的个数
        int count = 0;
        while(num != 0){
            if((num & 1) == 1){
                count++;
            }else{
                break; // 因为是连续签到,缺勤的就结束统计
            }
            num >>>= 1;
        }
        return Result.ok(count);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值