首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在数据库中存储EnumSet?

在数据库中存储EnumSet?
EN

Stack Overflow用户
提问于 2010-02-04 19:57:22
回答 8查看 9.5K关注 0票数 18

因此,在C++/C#中,您可以创建标志枚举来保存多个值,并且在数据库中存储单个有意义的整数当然是微不足道的。

在Java语言中有EnumSets,这似乎是在内存中传递枚举的一种很好的方法,但是如何将组合后的EnumSet输出为一个整数进行存储呢?有没有其他方法来解决这个问题呢?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-02-04 20:42:38

// From Adamski's answer
public static <E extends Enum<E>> int encode(EnumSet<E> set) {
    int ret = 0;

    for (E val : set) {
        ret |= 1 << val.ordinal();
    }

    return ret;
}

@SuppressWarnings("unchecked")
private static <E extends Enum<E>> EnumSet<E> decode(int code,
        Class<E> enumType) {
    try {
        E[] values = (E[]) enumType.getMethod("values").invoke(null);
        EnumSet<E> result = EnumSet.noneOf(enumType);
        while (code != 0) {
            int ordinal = Integer.numberOfTrailingZeros(code);
            code ^= Integer.lowestOneBit(code);
            result.add(values[ordinal]);
        }
        return result;
    } catch (IllegalAccessException ex) {
        // Shouldn't happen
        throw new RuntimeException(ex);
    } catch (InvocationTargetException ex) {
        // Probably a NullPointerException, caused by calling this method
        // from within E's initializer.
        throw (RuntimeException) ex.getCause();
    } catch (NoSuchMethodException ex) {
        // Shouldn't happen
        throw new RuntimeException(ex);
    }
}
票数 7
EN

Stack Overflow用户

发布于 2010-02-04 20:36:18

将序数存储为EnumSet的表示形式不是一个好主意。序号取决于枚举类(a related discussion is here)中定义的顺序。如果重构改变了Enum值的顺序,或者在中间引入了新的值,那么您的数据库可能很容易被破坏。

您必须引入单个枚举值的稳定表示。这些值也可以是int值,并在proposed way for the EnumSet中表示。

您的枚举可以实现接口,因此稳定的表示可以直接在枚举值中(改编自Adamski):

interface Stable{
    int getStableId();
}
public enum X implements Stable {
    A(1), B(2);

    private int stableId;

    X(int id){
        this.stableId = id;
    }

    @Override public int getStableId() {
        return stableId;
    }
}

改编自Adamski的代码:

public <E extends Stable> int encode(EnumSet<E> set) {
  int ret = 0;

  for (E val : set) {
    ret |= (1 << val.getStableId());
  }

  return ret;
}
票数 17
EN

Stack Overflow用户

发布于 2018-01-30 05:23:03

令我惊讶的是,没有人建议使用一个维护良好的库,而不是编写自己的库。上面的答案很准确,很有教育意义,但它只是鼓励人们复制和粘贴代码(然后大部分都忘记了)。

这是我的2分钱:

EnumSet<YourEnum> mySet = EnumSet.of(YourEnum.FIRST);
long vector = EnumUtils.generateBitVector(YourEnum.class, mySet);
EnumSet<YourEnum> sameSet = EnumUtils.processBitVector(YourEnum.class, vector);

请参阅https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/EnumUtils.html

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2199399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档