Java: EnumSet.copyOf——还有改进的空间吗?



我需要从Set创建一个EnumSet。我决定使用EnumSet#copyOf方法。然而,由于对该方法的限制:

the specified collection must contain at least one element (in order to determine the new enum set's element type)

需要确保集合不是空的。代码变成:

enum Color {RED, GREEN, BLUE}; Set<Color> set = ... // get it from somewhere if (set.isEmpty()) { return EnumSet.noneOf(Color.class); else return EnumSet.copyOf(set);

也许javac在确定传递给copyOf方法的集合的成员的正确类型方面存在真正的限制,但是我无法克服我必须诉诸于上面的东西来满足空集合的感觉。以下是我的问题:

  1. 这里不能接受空集合的限制到底是什么?

  2. copyOf(Collection<Enum<E>>)这样的方法签名可以解决这个问题吗?

  3. 如果是,还会产生哪些问题?

查看EnumSet的源代码,我看到了copyOf(Collection)至少需要一个元素的两个原因:

  • enum类检查可能的enum值的数量。这个数字用于确定使用哪种实现:RegularEnumSet使用单个long中的位来标记包含的元素(最多允许64个值),JumboEnumSet使用long[] (long数组)。
  • 元素的类型被存储并用于运行时类型检查(例如,子类中的add(E)方法调用EnumSet.typeCheck(E),可以抛出ClassCastException)。由于类型擦除,这似乎是必要的。

copyOf(Collection<Enum<E>>)这样的方法签名会解决吗这个问题?

签名已经基本上是你建议的,只是语法不同:

public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c)

这里E被定义为<E extends Enum<E>>,这意味着Collection<E>Collection<Enum<E>>的某种类型。

根据EnumSet。copyOf空集合抛出IllegalArgumentException,似乎有用的是一个接受元素类型参数的复制构造函数,这在创建新的EnumSet时是必要的:

EnumSet(Class<E>elementType, Enum<?>[] universe)
public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c, Class<E> elementType);

虽然节省很小,但获得的清晰度是显著的。对比:

if ( set.isEmpty() )
  return EnumSet.noneOf(Color.class);
else
  return EnumSet.copyOf(set);
return EnumSet.copyOf(set, Color.class);
intent只是将给定的set复制为EnumSet。简单、直接地表达这种意图似乎是最合适的。

相关内容

  • 没有找到相关文章

最新更新