【问题标题】:Storing and retrieving enums in SQLite with Java使用 Java 在 SQLite 中存储和检索枚举
【发布时间】:2016-08-31 23:43:23
【问题描述】:

我需要能够从 SQLite 数据库存储和检索枚举,我已经通过结合使用包装类和枚举来解决这个问题,但我觉得它的设计非常糟糕。

每次我想在枚举列表中添加一个新项目时,我都必须在三个不同的地方添加它。

枚举必须包含:

  • 一个int(或字符串)来表示它
  • 一个文本字符串,提供有关枚举本身的更多文本
  • 一种从数据库中恢复其状态的方法

目前是这样实现的:

public class items
{
    public enum types {
        FOO(0),
        BAR(1), 
        BAZ(2);

        private final int _value;
        types(int value){_value = value;}
        public int value(){return _value;}
    }

    public static types Get(int i)
    {
        switch(i)
        {
            case 0:
                return types.FOO;
            case 1:
                return types.BAR;
            case 2:
                return types.BAZ;   
            default: 
                return null;
        }
    }

    public static String Get(Typer type)
    {
        switch(type)
        {
            case FOO:
                return "This is foo!";
            case BAR:
                return "This is bar!";
            case BAZ:
                return "This is baz!";
            default:
                return "No good!";
        }
    }
}

有没有更好的方法来处理这个问题?

【问题讨论】:

    标签: java enums


    【解决方案1】:

    一个枚举值有FOO.ordinal()函数是一个值的数字表示。该函数返回它在零和n-1 之间的数字,其中n - 你有多少枚举值。然后您可以使用types.values()[i] 按数字检索值。但是你应该记住,不允许在中间重新排序或添加新的枚举,因为数字会改变。

    此外,您可以使用types.valueOf("FOO")FOO.name() 作为枚举值的字符串表示形式。使用起来更安全,因为它不依赖于声明顺序。

    【讨论】:

    • 但是如果要将枚举存储到字符串中,千万不要更改枚举值的名称..每个都有其优点和缺点
    • 我猜使用序数的风险更大,因为可以很容易地在两者之间添加一个新的枚举类型。但改名的可能性要小一些。嗯,这就是我的感觉,我可能错了
    • @RahulVerma 如果重要的话,只需进行测试——而且没有风险。但是存储单个 int 值通常比字符串更有效。
    【解决方案2】:

    您可以使用枚举名称进行存储和检索。

    types.valueOf("FOO") 应该提供 types.FOOtypes.FOO.name() 给你枚举的名称。

    如果你想通过成员变量来检索它,你可以这样做:

    public static Types byValue(final int value) {
        Types returnvalue = FOO; // default returnvalue
        for (final Types type : Types.values()) {
            if (type.value == value) {
                returnvalue = type;
                break;
            }
        }
        return returnvalue;
    }
    

    如果它对性能至关重要,您可以将所有类型放入以“值”为键的静态映射中。然后你不需要循环,只说valueMap.get(value)。映射应该在枚举中的静态块中初始化。

    对于额外的文本值,您可以为枚举提供第二个带有 getter 的 String 类型的成员变量。所以关联的 int 和 String 值只是在初始化中。

    例如,

    FOO(0,"Hello I'm Foo"),
    BAA(1,"Hello I'm Baa"),
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-30
      • 1970-01-01
      相关资源
      最近更新 更多