【java】redis的bitmap实现签到功能

功能:

        1.签到

        2.判断某天是否签到

        3.统计某月的签到情况

        4.统计某月连续签到了多少天

        5.统计某月一共签到了多少次

代码

1.依赖

<dependencies><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.0.1</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.18</version></dependency>
</dependencies>

2.用户签到

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import redis.clients.jedis.Jedis;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;public class UserSign {Jedis jedis;public UserSign(Jedis jedis) {this.jedis = jedis;}public String buildKey(int userId, Date date) {return Constant.SING_KEY + userId + ":" + simpleFormatDate(date);}/*** 用户签到** @param userId 用户id* @return 签到情况*/public boolean sign(int userId, Date date) {DateTime now = (DateTime) date;String key = buildKey(userId, now);//这里需要减一是因为偏移量是从0开始的int offset = now.dayOfMonth() - 1;return jedis.setbit(key, offset, true);}/*** 检测用户是否签到** @param userId* @param date* @return*/public boolean isSign(int userId, Date date) {DateTime dateTime = (DateTime) date;return jedis.getbit(buildKey(userId, date), dateTime.getDay() - 1);}/*** 统计签到情况** @param userId 用户id* @param date   日期对象* @return*/public Map<String, Boolean> getSignInfo(int userId, Date date) {Map<String, Boolean> map = new LinkedHashMap<String, Boolean>();//当月最后一天DateTime dateTime = (DateTime) date;String type = String.format("u%d", dateTime.getLastDayOfMonth());//查询当月所签到的二进制值List<Long> longs = jedis.bitfield(buildKey(userId, date), "get", type, "0");//判断当月是否有签到情况if (longs == null || longs.size() == 0) return null;Long aLong = longs.get(0);for (int i = dateTime.getLastDayOfMonth(); i > 0; i--) {DateTime now = DateTime.now();now.setField(DateField.DAY_OF_MONTH, i);/*如果二进制右移一位再左移一位等于原来的值,证明低位有0,断签例如  6的二进制 01100110 >>右移一位 = 0011 <<左移回来 0110 还是不变,证明低位有0*/if (aLong >> 1 << 1 == aLong) {map.put(simpleFormatDate(now, "yyyy-MM-dd"), false);} else {map.put(simpleFormatDate(now, "yyyy-MM-dd"), true);}//右移继续判断下一天aLong >>= 1;}return map;}/*** 统计连续签到** @param userId 用户id* @param date   日期对象* @return*/public int getContinuousSignNCount(int userId, Date date) {int count = 0;int nowDay = ((DateTime) date).dayOfMonth();//当月最后一天String type = String.format("u%d", nowDay);//查询当月所签到的二进制值List<Long> l = jedis.bitfield(buildKey(userId, date), "get", type, "0");//当月未签到if (l == null || l.size() == 0) return 0;//统计Long aLong = l.get(0);for (int i = 0; i < nowDay; i++) {/*如果二进制右移一位再左移一位等于原来的值,证明低位有0,断签例如  6的二进制 01100110 >>右移一位 = 0011 <<左移回来 0110 还是不变,证明低位有0*/if (aLong >> 1 << 1 == aLong) {//这里需要考虑当天没有签到的情况if (i > 0) break;} else {count += 1;}//右移继续判断下一天aLong >>= 1;}return count;}/*** 用户某月内一共签到了多少次** @param userId 用户id* @param date   日期对象* @return*/public long signCount(int userId, Date date) {return jedis.bitcount(buildKey(userId, date));}/*** 固定日期格式** @param date* @return*/public static String simpleFormatDate(Date date) {return new SimpleDateFormat("yyyyMM").format(date);}/*** 用户自定义日期格式*<>java的开闭原则</>* @param date* @param format* @return*/public static String simpleFormatDate(Date date, String format) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);return simpleDateFormat.format(date);}
}

3.测试 

import cn.hutool.core.date.DateTime;
import redis.clients.jedis.Jedis;import java.util.Map;
import java.util.Set;public class Test {public static void main(String[] args) throws InterruptedException {Jedis jedis = new Jedis("192.168.57.128", 6379);UserSign userSign = new UserSign(jedis);System.out.println("-----------------签到-----------------");DateTime now = DateTime.now();for (int i = 1; i <= 4; i++) {now.setDate(i);System.out.println(now);userSign.sign(100, now);}System.out.println("-----------------查看某一天是否签到-----------------");DateTime now1 = DateTime.now();boolean sign = userSign.isSign(100, now1);System.out.println(sign ? UserSign.simpleFormatDate(now1, "yyyy-MM-dd") + ":已签到" : "未签到");System.out.println("-----------------查看连续签到了几天-----------------");DateTime now2 = DateTime.now();int continuousSignNCount = userSign.getContinuousSignNCount(100, now2);System.out.println(UserSign.simpleFormatDate(now2) + "月连续签到了" + continuousSignNCount + "天");System.out.println("-----------------总体签到情况-----------------");Map<String, Boolean> signInfo = userSign.getSignInfo(100, DateTime.now());Set<Map.Entry<String, Boolean>> entries = signInfo.entrySet();for (Map.Entry<String, Boolean> entry : entries) {System.out.println(entry.getKey() + ":" + (entry.getValue() ? "√" : "X"));}System.out.println("-----------------统计一个月签到了多少天-----------------");DateTime now3 = DateTime.now();long l = userSign.signCount(100, now3);System.out.println(UserSign.simpleFormatDate(now3) + "月签到了" + l + "次");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/720350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity2023.1.19_ECS_DOTS

Unity2023.1.19_ECS_DOTS 盲学-盲目的学习&#xff1a; 懒着自己整理就看看别人整理的吧&#xff0c;整合一下逻辑通了不少&#xff1a; DOTS/data oriented technology stack-面向数据的技术栈 ECS/Entities-Component-System Unity-Entities包 Entities提供ECS架构面向数…

BUUCTF---[ACTF2020 新生赛]BackupFile1

1.题目描述 2.题目提示backup file &#xff0c;是备份文件的意思。点开链接&#xff0c;页面提示 3.查看源码没有什么有用信息&#xff0c;也没有登录界面&#xff0c;所以也不会用到蚁剑链接来找备份文件&#xff0c;所以大概率就是通过构造playload来查找备份文件。 4.备份…

kubectl 速查手册

资源对象文件 --- kind: Pod apiVersion: v1 metadata:name: myweblabels:app: nginx spec:containers:- name: webserverimage: nginx status: {} annotate # 更新资源所关联的注释信息 #-----------------------------------------# [rootmaster k8s]# kubectl apply -f m…

图像检测 - 模板匹配方法(算法详解)

1、介绍 在如今深度学习、神经网络遍地的世界,检测已经很常见了。在深度学习领域,关于目标检测也提出了很多很成熟的算法,例如双阶段的Fast-RCNN、单阶段的YOLO系列等等。 尤其是YOLO系列的不断更新迭代,目标检测的任务变得不再困难,可以做到实时检测的跟踪等等 但对于数…

新手想玩硬件,买单片机还是树莓派好?

新手想玩硬件&#xff0c;买单片机还是树莓派好&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#x…

Springboot+vue的船舶监造系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的船舶监造系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的船舶监造系统&#xff0c;采用M&#xff08;model&#xff09;V&#xff…

二百二十六、Linux——shell脚本查看今天日期、昨天日期、30天前日期、1月前日期

一、目的 由于磁盘资源有限&#xff0c;因为对原始数据的保存有事件限制&#xff0c;因为对于超过一定期限的数据文件则需要删除&#xff0c;要实现定期删除则第一步就是查看日期时间 二、在Linux中创建shell脚本 #! /bin/bash source /etc/profile nowdatedate --date0 da…

Linux 学习笔记(11)

十一、 资源监控 1 、 free 内存监控 语 法&#xff1a; free [-bkmotV][-s < 间隔秒数 >] 补充说明&#xff1a; free 指令会显示内存的使用情况&#xff0c;包括实体内存&#xff0c;虚拟的交换文件内存&#xff0c;共享内存区段&#xff0c;以 及系统核心使用的…

[计算机网络]:流量控制

一、流量控制简介 一条TCP连接的每一侧主机都为其设置了接收缓存&#xff0c;当TCP成功连接后&#xff0c;它发送的数据会放入接受缓存中。相关联的进程会从缓存中读取数据。但是存在一个问题&#xff0c;当某应用程序读取数据速率太慢&#xff0c;而发送数据一方不停的发送数…

5. 【Codeforces Round 927 (Div. 3)】B.查亚日历

B . 查亚日历 B.查亚日历 B.查亚日历 每次测试时限&#xff1a; 2 秒 每次测试时限&#xff1a;2 秒 每次测试时限&#xff1a;2秒 每次测试的内存限制&#xff1a; 256 兆字节 每次测试的内存限制&#xff1a;256 兆字节 每次测试的内存限制&#xff1a;256兆字节 题目描述 查…

【数据结构】复杂度详解

目录 &#xff08;一&#xff09;算法的复杂度 &#xff08;二&#xff09;时间复杂度 &#xff08;1&#xff09;练笔解释&#xff1a; i&#xff0c;示例1 ii&#xff0c;示例2 iii&#xff0c;二分查找 iv&#xff0c;斐波那契 &#xff08;三&#xff09;空间复杂度…

英福康INFICON真空计MPG400MPG401使用说明PPT讲解课件

英福康INFICON真空计MPG400MPG401使用说明PPT讲解课件

Java解决杨辉三角

Java解决杨辉三角 01 题目 给定一个非负整数 *numRows&#xff0c;*生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRo…

浏览器常见进程和线程

文章目录 进程和线程的联系和区别早期浏览器Chrome 打开一个页面有多少进程&#xff1f;分别是哪些渲染进程中的线程说下浏览器的进程、线程模型&#xff0c;线程模型中的每个线程都是干嘛用的&#xff1f;你知道哪些进程间通信的方式&#xff1f;多标签之间怎么通信&#xff1…

LeetCode 3069.将元素分配到两个数组中 I

给你一个下标从 1 开始、包含 不同 整数的数组 nums &#xff0c;数组长度为 n 。 你需要通过 n 次操作&#xff0c;将 nums 中的所有元素分配到两个数组 arr1 和 arr2 中。在第一次操作中&#xff0c;将 nums[1] 追加到 arr1 。在第二次操作中&#xff0c;将 nums[2] 追加到 …

计网面试题整理下

1. HTTP常见的状态码有哪些&#xff1f; 常见状态码&#xff1a; 200&#xff1a;服务器已成功处理了请求。 通常&#xff0c;这表示服务器提供了请求的网页。301 &#xff1a; (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时&am…

python c++混合编程-cmake

利用cmake将c文件编译成.so库文件&#xff0c;通过import调用 简单调用高级用法-调用c项目 简单调用 创建trypybind.cpp文件 #include <pybind11/pybind11.h> #include <iostream> namespace py pybind11; using namespace std; //绑定一个函数 int main() { co…

前端面试 跨域理解

2 实现 2-1 JSONP 实现 2-2 nginx 配置 2-2 vue 开发中 webpack自带跨域 2 -3 下载CORS 插件 或 chrome浏览器配置跨域 2-4 通过iframe 如&#xff1a;aaa.com 中读取bbb.com的localStorage 1)在aaa.com的页面中&#xff0c;在页面中嵌入一个src为bbb.com的iframe&#x…

vscode ctrl+左键不能转到定义修理

找到C_Cpp: Intelli Sense Engine&#xff0c;改成disable&#xff0c;再改成默认就可以了原来是当前的工作目录不包括函数定义的文件&#xff0c;调整一下工作目录即可。或者&#xff0c; "includePath": [ "${workspaceFolder}/**", …

云原生环境中的自动化测试成功案例分析

在云原生环境中,DevOps通过结合云原生技术和持续集成/持续部署(CI/CD)流程,实现了软件的快速交付和质量保证。自动化测试是DevOps实践中的重要组成部分,它能够提高测试的效率和覆盖率,从而加速软件的交付周期并确保软件质量[3][5][13]。 成功案例之一是视野数科利用SAE和…