2023/9/20(基于bitmap的用户登录状态记录)

114 阅读1分钟

为什么要基于一个Integer类型做用户月登录记录

其实Integer类型的范围是2^31 ~2^31 - 1

即我们只要将他看成2进制位,他就有31位,刚好可以记录一个月用户登录的情况

例如 0101

则该用户在这个月的1号和3号登录了,用 0 和 1来记录用户登录的情况

这种方案同样适用于标签系统的设计

package login;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.LinkedHashMap;
import java.util.Map;

public class monthLoginUtil {
    /**
     * @param bitmap    记录表
     * @param startDay  记录表的开始日期
     * @param searchDay 要搜索的日期
     * @return
     */
    public static boolean isMonthLogin(Integer bitmap, LocalDate startDay, LocalDate searchDay) {
        long days = ChronoUnit.DAYS.between(startDay, searchDay);//获取时间差
        long day = 1L << days;
        return (bitmap & day) != 0;
    }

    /**
     * 默认为当前月登录
     *
     * @param bitmap
     * @param searchDay
     * @return
     */
    public static boolean CurrentMonthLogin(Integer bitmap, LocalDate searchDay) {
        LocalDate now = LocalDate.now();
        LocalDate localDate = now.withDayOfMonth(1);
        return isMonthLogin(bitmap, localDate, searchDay);
    }

    /**
     * 判断一个月内的登录记录
     *
     * @param bitmap
     * @return
     */
    public static Map<Integer, Boolean> MonthlyLogins(Integer bitmap) {
        int day = 1;
        Map<Integer, Boolean> result = new LinkedHashMap<>();
        for (int i = 1; i < 32; i++) {
            if ((bitmap & day) != 0) {
                result.put(i, true);
            } else {
                result.put(i, false);
            }
            day = day << 1;
        }
        return result;

    }

    /**
     * 当日进行了登录
     *
     * @param bitmap 记录表
     * @return
     */
    public static Integer currentDayLogin(Integer bitmap) {
        LocalDate now = LocalDate.now();
        LocalDate localDate = now.withDayOfMonth(1);
        return dayLogin(bitmap, localDate, now);
    }

    /**
     * 指定日期进行了登录
     *
     * @param bitmap 记录表
     * @param startDay 开始时间
     * @param LoginDate 登录时间
     * @return
     */
    public static Integer dayLogin(Integer bitmap, LocalDate startDay, LocalDate LoginDate) {
        int days = (int) ChronoUnit.DAYS.between(startDay, LoginDate);//获取时间差
        int day = 1 << days;
        return bitmap ^ day;
    }
}
package login;

import java.util.Map;

public class Client {
    public static void main(String[] args) {
        Integer integer = monthLoginUtil.currentDayLogin(0);
        Map<Integer, Boolean> map = monthLoginUtil.MonthlyLogins(integer);
        map.forEach((k, v) -> {
            System.out.println(k + "===>" + v);
        });
    }
}