简体   繁体   English

用Java创建EnumSet数组

[英]Creating an EnumSet array in Java

I am trying to create an EnumSet array (using Eclipse). 我正在尝试创建一个EnumSet数组(使用Eclipse)。

Version 1: 版本1:

EnumSet mySet[] = new EnumSet[3];

This works, but I get a warning: "EnumSet is a raw type. References to generic type EnumSet should be parameterized". 这可行,但是我得到警告:“ EnumSet是原始类型。对通用类型EnumSet的引用应参数化”。

Version 2 as suggested: 建议的版本2:

EnumSet<MyEnum> mySet[] = new EnumSet[3];

Again a warning: "Type safety: The expression of type EnumSet[] needs unchecked conversion to conform to EnumSet[]" 再次发出警告:“类型安全:EnumSet []类型的表达式需要未经检查的转换才能符合EnumSet []”

Version 3 as suggested: 建议的版本3:

EnumSet<MyEnum> mySet[] = new EnumSet<MyEnum>[3];

Now I get an error! 现在我得到一个错误! "Cannot create a generic array of EnumSet" “无法创建EnumSet的通用数组”

What should I do? 我该怎么办? Will a not parameterized EnumSet have performance issues? 未参数化的EnumSet是否会出现性能问题?

You cannot create an array of concrete parameterized type, because it is not type safe. 您不能创建具体参数化类型的数组,因为它不是类型安全的。 The reason being, the concrete parameterized type are not reified, whereas arrays are reified entity. 原因是,具体的参数化类型未统一,而数组是统一的实体。

You can however create an array of raw type, or unbounded wildcard type: 但是,您可以创建原始类型或无界通配符类型的数组:

EnumSet<?> mySet[] = new EnumSet<?>[3];

The reason this works is because rawtypes and unbounded wildcard types are reified. 之所以起作用,是因为原始类型和无限制的通配符类型都已实现。 So, it's typesafe to create an array with such component type. 因此,使用这种组件类型创建数组是类型安全的。

By reified, we mean the type information is available at runtime. 所谓修饰,是指类型信息在运行时可用。 This is not true with concrete parameterized type, because the type information is lost as a process of type erasure. 对于具体的参数化类型,情况并非如此,因为类型信息会随着类型擦除的过程而丢失。 However, for raw types, there is no type at all that can be lost. 但是,对于原始类型,根本不会丢失任何类型。 Same is true for <?> types. 对于<?>类型也是如此。 Since EnumSet<?> is a supertype of all instantiation of generic type EnumSet<T> , so there is no specific type information about EnumSet<?> at compile time that can be lost at runtime. 由于EnumSet<?>是泛型类型EnumSet<T>的所有实例的超类型,因此在编译时没有关于EnumSet<?>特定类型信息,该信息可以在运行时丢失。

Another option is to simply create a list. 另一种选择是简单地创建一个列表。 This is far more better than mixing arrays with generic types: 这比混合使用泛型类型的数组要好得多:

List<EnumSet<MyEnum>> mySets = new ArrayList<>();

Answer by Rohit Jain is correct, only I would like to add extended example. Rohit Jain的回答是正确的,只有我想添加扩展示例。 It uses casting for initialization. 它使用强制转换进行初始化。

Definition: 定义:

public enum CellState {
  MINE_EMPTY,MINE_NEAR_1,MINE_NEAR_2,MINE_NEAR_3,MINE_NEAR_4,MINE_NEAR_5,MINE_NEAR_6,
  MINE_NEAR_7, MINE_NEAR_8,MINE,CLICK_OPEN, CLICK_MARK;

  public static EnumSet<CellState> ALL_OPTS = EnumSet.allOf(CellState.class);
  public static EnumSet<CellState> NOT_MINE = EnumSet.of(MINE_EMPTY,MINE_NEAR_1,MINE_NEAR_2,MINE_NEAR_3,MINE_NEAR_4,MINE_NEAR_5,MINE_NEAR_6,
        MINE_NEAR_7, MINE_NEAR_8); 
}

} }

Declaration: 宣言:

  public EnumSet<CellState>[][] minefield; // 2-dimensional array

Initialization (casting needed): 初始化(需要广播):

minefield = (EnumSet<CellState>[][]) new EnumSet<?>[width][height];
for (int y = 0; y < height; y++) {
  for (int x = 0; x < width; x++) {
    minefield[x][y] = EnumSet.allOf(CellState.class);
  }
}

Usage: 用法:

if (!minefield[x][y].contains(CellState.MINE)) {
      minefield[x][y].add(minesNear(x, y));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM