Java: EnumSet.copyOf — is there a room for improvement?

*爱你&永不变心* 提交于 2019-12-13 00:04:07

问题


I need to create an EnumSet from a Set. I decided to use the EnumSet#copyOf method. However, because of a restriction on this method:

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

I need to ensure that the collection is not empty. The code then becomes:

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);

Perhaps there is a real limitation on javac to determine the correct type of members of the collection passed to copyOf method, but I can't get over the feeling that I have to resort to something like above to cater for the empty collection. Here are my questions then:

  1. Exactly what is the limitation that the empty collection can't be accepted here?

  2. Would a method signature like copyOf(Collection<Enum<E>>) have solved this problem?

  3. If yes, what other problems would it have created?


回答1:


Looking at the source code of EnumSet, I see two reasons to require at least one element for copyOf(Collection):

  • The enum class is checked for the number of possible enum values. This number is used to determine which implementation is used: RegularEnumSet uses the bits in a single long to mark the contained elements (allowing up to 64 values), JumboEnumSet uses a long[] (long array).
  • The type of the element is stored and used for a runtime type check (for example, the add(E) method in the subclasses calls EnumSet.typeCheck(E) which can throw a ClassCastException). This seems to be necessary due to type erasure.

Would a method signature like copyOf(Collection<Enum<E>>) have solved this problem?

The signature already is basically what you suggest, just with different syntax:

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

Here E is defined as <E extends Enum<E>> which means Collection<E> is some type of Collection<Enum<E>>.




回答2:


In light of EnumSet.copyOf empty collection throws IllegalArgumentException, what would seem to be of use would be a copy constructor which accepted an element type parameter, as is necessary when creating a new EnumSet:

EnumSet(Class<E>elementType, Enum<?>[] universe)

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

While the savings are small, the gain in clarity is significant. Contrast:

if ( set.isEmpty() )
  return EnumSet.noneOf(Color.class);
else
  return EnumSet.copyOf(set);

return EnumSet.copyOf(set, Color.class);

The intent is simply to copy a given set as an EnumSet. A simple, direct, expression of that intent seems most appropriate.



来源:https://stackoverflow.com/questions/32722808/java-enumset-copyof-is-there-a-room-for-improvement

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!