我需要从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
方法的集合成员的正确类型,但是我无法克服这种感觉,我必须求助于上面的事情以迎合空集。这是我的问题:
这里无法接受空集合的限制是什么?
像copyOf(Collection<Enum<E>>)
这样的方法签名是否解决了这个问题?
如果是,它会产生哪些其他问题?
答案 0 :(得分:0)
查看EnumSet
的源代码,我发现需要copyOf(Collection)
至少一个元素的两个原因:
enum
类的可能enum
值的数量。此数字用于确定使用的实现:RegularEnumSet
使用单个long
中的位标记包含的元素(允许最多64个值),JumboEnumSet
使用{{1} (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>
的某种类型。
答案 1 :(得分:0)
根据EnumSet.copyOf empty collection throws IllegalArgumentException,似乎有用的是复制构造函数,该构造函数接受元素类型参数,这在创建新的EnumSet时是必需的:
<!--uses-permission android:name="android.permission.SEND_SMS" /-->
<uses-permission android:name="android.permission.INTERNET" />
<!--uses-permission android:name="android.permission.CALL_PHONE" /-->
<!--tools:node="remove"-->
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<service
android:name="com.premar.radiomunabuddu.RadioMediaPlayerService"
android:enabled="true" >
</service>
<receiver android:name="com.premar.radiomunabuddu.IntentReceiver">
<intent-filter>
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
<activity
android:name="com.premar.radiomunabuddu.HomeActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.premar.radiomunabuddu.AboutActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.premar.radiomunabuddu.HomeActivity" />
</activity>
</application>
虽然节省的费用很少,但清晰度却很可观。对比:
EnumSet(Class<E>elementType, Enum<?>[] universe)
public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c, Class<E> elementType);
意图只是将给定集合复制为EnumSet。简单,直接地表达这种意图似乎是最合适的。