2013-10-10 101 views
0

多次调用特定枚举类的values()函数是否存在任何低效率?枚举值()方法效率

我已经看到现有代码的实例,其中values()的结果被缓存以供重用。这有用吗?

public enum Blah { 

    private static final Blah [] _myValues = values() 

    ... 

    public static Blah findBlahFromName(String name) { 
     for (Blah blah : _myValues) { 
      ... 
     } 
    } 

} 
+0

在这种特殊情况下,我倾向于使用Guava'ImmutableMap ',因为它可以安全共享,可以打包,并且使用IMO更简单。 – chrylis

+0

你可以看到如何检索这些[这里](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Class.java#Class .getEnumConstants%28%29) – Obicere

+0

这里的缓存被称为微优化。除非真的如此,enum已经成为您的应用程序的瓶颈。 – Kayaman

回答

4

如果多次使用它,在枚举本身内缓存values()的结果是一个好主意。这是因为,每次调用values()方法时,都会创建一个新数组。所以,这真的不是必需的,因为你总是会得到相同的数组元素。

如注释中所述,共享缓存数组不会是线程安全的,因为其他线程可以修改数组中的索引,因为它是可变的。一个选项是将元素包装在List<YourEnum>中,并使用Collections.unmodifiableList()共享该列表。

+2

虽然* not *可以与不信任的人共享'values()'的缓存副本,因为Java中的数组总是可变的,并且有人可能会使用这些值的副本。 – chrylis

+0

@chrylis好点。 –

+0

或者只是使用['Enum.valueOf'](http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#valueOf%28java.lang.Class,java.lang。字符串%29),如果您知道枚举的['name()'](http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#name())。我推断创建一个新阵列的代价是大多数代码可以忽略不计。 –

3

是的,这是低效的,但还有另一种方式来做到这一点,这不是几乎一样昂贵:

EnumSet.allOf(MyEnum.class); 

EnumSet有专门布线到JDK,使其能够重复使用的底层数组。