2的幂指数工具类:解决数据库一个字段存多个类型的问题

2023-12-25  本文已影响0人  柳岸花开

背景

在实际的数据库设计中,有时会遇到一个字段需要存储多个状态或类型的情况。为了高效地表示和操作这些状态,我们可以利用二进制中2的幂指数的特性。本文介绍了一个Java工具类,通过位运算来处理这类问题,以提高数据库字段的灵活性和性能。

工具类介绍

package com.itrus.uc.common.util;

import com.itrus.pc.core.exception.ProductCenterException;
import com.itrus.uc.common.enums.ErrorCode;
import com.itrus.uc.common.exception.UserCenterException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.util.*;

/**
 * 2的幂指数 工具类,解决数据库一个字段存多个类型的问题
 *
 * @author zhanghongliu
 */
@Slf4j
public class PowerOf2Util {

    // ...(略,省略了类的声明)

    /**
     * 根据多个状态合并成最终结果
     * 例:
     * [1,2] -> 3
     * [1,4] -> 5
     *
     * @return
     */
    public static int merge(Collection<Integer> status) {
        int result = 0;
        if (status == null || status.isEmpty()) {
            return result;
        }
        for (Integer item : status) {
            // 如果不是2的整数次幂
            if (!isPowOfTow(item)) {
                log.warn("参数错误,item={},不是2的整数次幂");
                throw new UserCenterException(ErrorCode.COMPANY_PARAM_ERROR);
            }
            result |= item.intValue();
        }
        return result;
    }

    /**
     * 判断是否是 2 的整数次幂
     * <p>
     * 2 的整数次幂数,二进制第一位是 1 其余位都是 0
     * 2 的整数次幂数减 1,二进制第一位是 0,其余为都是 1
     * 两个数与运算结果为 0 说明是 2 的整数次幂
     *
     * @param i
     * @return
     */
    private static boolean isPowOfTow(Integer i) {
        if (i == null || i == 0) {
            return false;
        }
        return (i & (i - 1)) == 0;
    }

    /**
     * 指数和分解,输入 7 输出 1 2 4
     */
    public static List<Integer> atomsOfSum(int sum) {
        List<Integer> list = new ArrayList<>();
        int i = 1;
        while (i <= sum) {
            if ((i & sum) != 0) {
                list.add(i);
            }
            i <<= 1;
        }
        return list;
    }

    /**
     * 包含某个值的所有指数和的集合,总和为7,含有1的 输出 1 3 5 7
     */
    public static List<Integer> sumsOfContainAtom(int sum, int atom) {
        if (!isPowOfTow(atom)) {
            log.warn("参数错误,item={},不是2的整数次幂");
            throw new UserCenterException(ErrorCode.COMPANY_PARAM_ERROR);
        }
        List<Integer> list = new ArrayList<>();
        int i = 1;
        for (; i <= sum; i++) {
            if ((atom & i) == atom) {
                list.add(i);
            }
        }
        return list;
    }
}

使用示例

合并状态

List<Integer> statusList = Arrays.asList(1, 2);int mergedResult = PowerOf2Util.merge(statusList);System.out.println("合并状态:" + mergedResult);

分解指数和

int sumToDecompose = 7;List<Integer> atoms = PowerOf2Util.atomsOfSum(sumToDecompose);System.out.println("指数和分解:" + atoms);

包含某个值的指数和

int totalSum = 7;int atomToCheck = 1;List<Integer> sums = PowerOf2Util.sumsOfContainAtom(totalSum, atomToCheck);System.out.println("包含值的指数和:" + sums);

总结

通过使用2的幂指数工具类,我们可以更高效地处理数据库字段存储多个类型的情况。这种技术可以提高代码的可读性和性能,使得在业务逻辑中处理状态变更更加方便。在实际应用中,可以根据业务需求灵活运用这个工具类,为系统设计提供更多的可能性。

上一篇下一篇

猜你喜欢

热点阅读