java enum 对标 .net 的enum [Flags]

一、前景

C#中的枚举中我们使用[Flags]来对枚举进行 |(与) 运算,比如这样:DemoEnum demoEnum = DemoEnum.One|DemoEnum.Two;
然后我们在使用的过程中,可以对 demoEnum.HasFlag(DemoEnum.Two)进行验证是否包含 Demo.Two 枚举值,但是JAVA中不支持枚举间的 与 运算,so 当前文章就诞生了。

二、枚举样例Demo

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 星期
 */
public enum DemoEnum {
    one("周一", 1),
    two("周二", 2),
    three("周三", 4),
    four("周四", 8),
    five("周五", 16),
    six("周六", 32),
    seven("周日", 64);

    /**
     * 名称
     */
    private String weekDayName;
    /**
     * 索引
     */
    private int index;

    /**
     * 当前星期状态键值对
     */
    private static final Map<Integer, DemoEnum> weekStateMap = Arrays.stream(DemoEnum.values()).collect(Collectors.toMap(DemoEnum::getIndex, v -> v));

    DemoEnum(String name, int index) {
        this.weekDayName = name;
        this.index = index;
    }

    public String getWeekDayName() {
        return weekDayName;
    }

    public void setWeekDayName(String weekDayName) {
        this.weekDayName = weekDayName;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public DemoEnum indexOf(int index) {
        return weekStateMap.get(index);
    }

    /**
     * 根据提供的枚举值,获取该值中包含的所有枚举对象(拆分枚举合计值为枚举列表)
     *
     * @param value 提供查询的枚举值(供拆分的枚举合计值,由一个或多个枚举index相加的值)
     * @return 返回符合条件的枚举列表
     */
    public static List<DemoEnum> getWeeks(int value) {
        List<DemoEnum> result = new ArrayList<>();
        if (weekStateMap.containsKey(value)) {
            result.add(weekStateMap.get(value));
            return result;
        }
        int currentValue = value;
        do {
            final int tempValue = currentValue;
            int maxValue = weekStateMap.keySet().stream().filter(f -> f <= tempValue).max(Integer::compare).get();
            result.add(weekStateMap.get(maxValue));
            currentValue -= maxValue;
        } while (currentValue > 0);
        return result;
    }

    /**
     * 检查当前枚举值是否在选中枚举列表中存在
     *
     * @param weekDayTotalValue 已选中枚举列表合计值(由一个或多个枚举index相加的值)
     * @param weekDayValue      待验证的枚举值(单个枚举index值,支持多个)
     * @return 返回验证枚举值是否在选中列表中
     */
    public static boolean hasWeekDay(int weekDayTotalValue, int weekDayValue) {
        if (!weekStateMap.containsKey(weekDayValue)) {
            System.out.println("暂时不支持多个枚举包含,若有需要加上也简单。。。");
            return false;
        }else {
            int currentValue = weekDayTotalValue;
            int maxValue = 0;
            do {
                final int tempValue = currentValue;
                maxValue = weekStateMap.keySet().stream().filter(f -> f <= tempValue).max(Integer::compare).get();
                if (maxValue == weekDayValue)
                    return true;
                currentValue -= maxValue;
            } while (currentValue > 0);
        }
        return false;
    }

    @Override
    public String toString() {
        return weekDayName;
    }
}

三、测试代码

    public static void main(String[] args) throws Exception {
        //工作日设置
        int weekDayTotal = DemoEnum.one.getIndex()|DemoEnum.two.getIndex()|DemoEnum.three.getIndex()|DemoEnum.four.getIndex()|DemoEnum.five.getIndex();
        //根据工作日,获取工作日集合
        List<DemoEnum> weeks = DemoEnum.getWeeks(weekDayTotal);
        System.out.println("设置的工作日如下:");
        for(DemoEnum week: weeks){
            System.out.println(week);
        }
        System.out.println("================================");
        DemoEnum week = DemoEnum.one;
        System.out.println(week+"是否在设置的工作日中?");
        System.out.println(DemoEnum.hasWeekDay(weekDayTotal,week.getIndex()));
        week = DemoEnum.six;
        System.out.println(week+"是否在设置的工作日中?");
        System.out.println(DemoEnum.hasWeekDay(weekDayTotal,week.getIndex()));
}

输出结果:

设置的工作日如下:
周五
周四
周三
周二
周一
================================
周一是否在设置的工作日中?
true
周六是否在设置的工作日中?
false

posted on 2022-11-23 03:07  Jalan·Wang  阅读(79)  评论(0编辑  收藏  举报

导航