Enum.values() vs EnumSet.allOf( )。哪一个更可取?

2022-08-31 14:45:38

我在引擎盖下寻找它看起来非常有效,特别是对于小于64个值的枚举。EnumSet.allOf

基本上,所有集合都共享所有可能的枚举值的单个数组,唯一的另一条信息是位掩码,如果是一次性设置的。allOf

另一方面,Enum.values()似乎有点黑魔法。此外,它返回一个数组,而不是一个集合,因此在许多情况下,它必须用 Arrays.asList( ) 进行修饰,才能在需要集合的任何地方使用。

那么,应该比?EnumSet.allOfEnum.values

更具体地说,应该使用哪种形式的迭代器:for

for ( final MyEnum val: MyEnum.values( ) );

for ( final MyEnum val: EnumSet.allOf( MyEnum.class ) );

答案 1

因为我没有收到关于哪一个更有效的问题的答案,所以我决定做一些自己的测试。

我已经测试了 迭代 , 和 .我已经为不同的枚举大小重复了这些测试10,000,000次。以下是测试结果:values()Arrays.asList( values() )EnumSet.allOf( )

oneValueEnum_testValues         1.328
oneValueEnum_testList           1.687
oneValueEnum_testEnumSet        0.578

TwoValuesEnum_testValues        1.360
TwoValuesEnum_testList          1.906
TwoValuesEnum_testEnumSet       0.797

ThreeValuesEnum_testValues      1.343
ThreeValuesEnum_testList        2.141
ThreeValuesEnum_testEnumSet     1.000

FourValuesEnum_testValues       1.375
FourValuesEnum_testList         2.359
FourValuesEnum_testEnumSet      1.219

TenValuesEnum_testValues        1.453
TenValuesEnum_testList          3.531
TenValuesEnum_testEnumSet       2.485

TwentyValuesEnum_testValues     1.656
TwentyValuesEnum_testList       5.578
TwentyValuesEnum_testEnumSet    4.750

FortyValuesEnum_testValues      2.016
FortyValuesEnum_testList        9.703
FortyValuesEnum_testEnumSet     9.266

这些是从命令行运行的测试的结果。当我从 Eclipse 运行这些测试时,我得到了 压倒性的支持。基本上,它甚至比小枚举还要小。我相信性能提升来自循环中数组迭代器的优化。testValuesEnumSetfor ( val : array )

另一方面,一旦你需要一个java.util.Collection来传递,就会松散到,特别是对于小枚举,我相信在任何给定的代码库中,它都会占多数。Arrays.asList( )EnumSet.allOf

所以,我会说你应该使用

for ( final MyEnum val: MyEnum.values( ) )

Iterables.filter(
    EnumSet.allOf( MyEnum.class ),
    new Predicate< MyEnum >( ) {...}
)

并且只在绝对需要的地方使用。Arrays.asList( MyEnum.values( ) )java.util.List


答案 2

您应该使用对您来说最简单,最清晰的方法。在大多数情况下,性能不应成为考虑因素。

恕我直言:这两个选项都表现不佳,因为它们都会创建对象。第一种情况下一个,第二个情况中有三个。出于性能原因,您可以构造一个常量来保存所有值。