【问题标题】:Container of Enums in javajava中的枚举容器
【发布时间】:2014-08-17 20:53:26
【问题描述】:

在 Java 中我可以这样做:

    enum Color {RED, BLUE, GREEN };
    enum Weight {LIGHT, HEAVY }

    Enum e = Color.RED;
    assertEquals(Color.RED, e);
    e = Weight.HEAVY;
    assertEquals(Weight.HEAVY, e);

我可以将枚举放在 Map 中并且仍然有效:

    Map<String, Enum> map = Maps.newHashMap();
    map.put("color", Color.RED);
    map.put("weight", Weight.HEAVY);
    assertEquals(Color.RED, map.get("color"));
    assertEquals(Weight.HEAVY, map.get("weight"));

但是,我不能对枚举集合做同样的事情。

   List<Enum> enumList = new ArrayList<Color>();  //error

这在 Java 中是不允许的还是我做错了?

有没有更好的方法来维护属性到代表它们的枚举的映射?

【问题讨论】:

  • 您在Map 示例与List 示例中做的事情不同。你看到了吗? (类型参数,推断和提供。)
  • 另外,不要使用原始类型。
  • “List 不是 List 的子类型”似乎是我在这里所缺少的。那么我怎样才能一般地存储不同的枚举集合呢?
  • 为什么你想要一个枚举列表而不知道它们是什么类型的枚举,例如,它们是颜色、权重还是其他什么?这有什么可能的用途?

标签: java enums


【解决方案1】:

如果每个枚举只有 1 个值要存储:

Map<Class<? extends Enum>, Enum<?>> map = new HashMap<Class<? extends Enum>, Enum<?>>();
map.put(Color.class, Color.BLUE);
map.put(Weight.class, Weight.LIGHT);
Color color = getFromMap(map, Color.class);

private static <T> T getFromMap(Map<Class<? extends Enum>, Enum<?>> map, Class<T> itemClass) {
    return (T) map.get(itemClass);
}

否则

List<Enum<?>> list = new ArrayList<Enum<?>>();
list.add(Color.BLUE);
list.add(Weight.LIGHT);
Color fromList = getFromList(list, 1, Color.class);

private static <T> T getFromList(List<Enum<?>> list, int i, Class<Color> outType) {
    return (T) list.get(i);
}

【讨论】:

    【解决方案2】:
    List<? extends Enum> enumList = new ArrayList<Color>();
    

    ColorEnum子类型,但List&lt;Color&gt; 不是List&lt;Enum&gt;子类型

    您必须明确地说“Enum 的子类型的列表”,在 Java 中是:

    List&lt;? extends Enum&gt;

    【讨论】:

      【解决方案3】:

      Enum 是一个泛型类,所以给它一个泛型参数:

      List<Enum<Colour>> l = new ArrayList<Enum<Colour>>();
      

      可以简写为:

      List<Colour> l = new ArrayList<Colour>();
      

      以下是有效代码:

          List<Enum<Colour>> ecl = new ArrayList<Enum<Colour>>();
          List<Colour> cl = new ArrayList<Colour>();
          ecl.add(Colour.Blue);
          cl.add(Colour.Blue);
      

      【讨论】:

        【解决方案4】:

        您必须使用通配符进行这种分配:

        List<? extends Enum> enumList = new ArrayList<Color>();
        

        通配符允许这种赋值,尽管你不能对集合做某些事情......例如添加扩展 Enum 的元素(因为你不知道类型引用的对象)。您只能从 Enum 及以上获取元素。

        如果您希望能够不断添加元素,请将数组列表设为:

        ArrayList<Enum>
        

        【讨论】:

          【解决方案5】:

          ArrayList 将始终充当ListColor 将始终充当Enum

          但是: ArrayList&lt;Color&gt;始终充当List&lt;Enum&gt;

          例子:

              List<Enum> EvilList = new ArrayList<Color>();
              EvilList.add(Some other Enum);
              // Because EvilList is, in its definition, a List<Enum>, allowing your code to
              // compile would break the type safety that generics are meant to preserve.
          

          但是请注意,List&lt;Color&gt; 不会破坏泛型类型安全。

          【讨论】:

            【解决方案6】:

            您列表的类型参数似乎不正确,

            List<Enum> enumList = new ArrayList<Color>();
            

            应该是

            List<Enum> enumList = new ArrayList<Enum>();
            

            或(使用diamond operator - Java 7 及更高版本)

            List<Enum> enumList = new ArrayList<>();
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2010-12-10
              • 1970-01-01
              • 2011-07-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多