检查Java中是否存在enum
无论如何,是否可以通过将枚举与给定字符串进行比较来检查枚举是否存在? 我似乎找不到任何这样的功能。 我可以尝试使用 valueOf
方法并捕获异常,但我被告知捕获运行时异常不是一个好的做法。 有人有什么想法吗?
Is there anyway to check if an enum exists by comparing it to a given string? I can't seem to find any such function. I could just try to use the valueOf
method and catch an exception but I'v been taught that catching runtime exceptions is not good practice. Anybody have any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
如果我需要这样做,我有时会构建一个
Set
名称,甚至是我自己的Map
- 然后你可以检查一下。有几点值得注意:
values()
- 它每次都必须创建并填充一个新数组。 要迭代所有元素,请使用EnumSet.allOf
对于没有大量元素的枚举来说效率更高。示例代码:
当然,如果您只有几个名字,这可能有点过分了——当 n 足够小时,O(n) 解决方案通常会胜过 O(1) 解决方案。 这是另一种方法:
If I need to do this, I sometimes build a
Set<String>
of the names, or even my ownMap<String,MyEnum>
- then you can just check that.A couple of points worth noting:
values()
frequently - it has to create and populate a new array each time. To iterate over all elements, useEnumSet.allOf
which is much more efficient for enums without a large number of elements.Sample code:
Of course, if you only have a few names this is probably overkill - an O(n) solution often wins over an O(1) solution when n is small enough. Here's another approach:
我不认为有一种内置的方法可以在不捕获异常的情况下做到这一点。 您可以改为使用如下内容:
编辑: 正如 Jon Skeet 所指出的,
values()
的工作原理是在每次调用时克隆一个私有后备数组。 如果性能至关重要,您可能只想调用values()
一次,缓存数组,然后迭代它。此外,如果您的枚举具有大量值,Jon Skeet 的映射替代方案可能比任何数组迭代的性能更好。
I don't think there's a built-in way to do it without catching exceptions. You could instead use something like this:
Edit: As Jon Skeet notes,
values()
works by cloning a private backing array every time it is called. If performance is critical, you may want to callvalues()
only once, cache the array, and iterate through that.Also, if your enum has a huge number of values, Jon Skeet's map alternative is likely to perform better than any array iteration.
我最喜欢的库之一:Apache Commons。
EnumUtils 可以轻松做到这一点。
以下是使用该库验证枚举的示例:
One of my favorite lib: Apache Commons.
The EnumUtils can do that easily.
Following an example to validate an Enum with that library:
我不知道为什么有人告诉你捕获运行时异常是不好的。
使用
valueOf
并捕获IllegalArgumentException
适合将字符串转换/检查为枚举。I don't know why anyone told you that catching runtime exceptions was bad.
Use
valueOf
and catchingIllegalArgumentException
is fine for converting/checking a string to an enum.根据 Jon Skeet 的回答,我创建了一个类,可以在工作中轻松完成此操作:
以及单元测试:
请注意,我使用 Guava 制作 ImmutableMap 但实际上您可以使用法线贴图,我认为因为贴图永远不会返回...
Based on Jon Skeet answer i've made a class that permits to do it easily at work:
And the unit test:
Notice that i used Guava to make an ImmutableMap but actually you could use a normal map i think since the map is never returned...
大多数答案建议使用带有 equals 的循环来检查枚举是否存在,或者使用带有 enum.valueOf() 的 try/catch。 我想知道哪种方法更快并尝试了一下。 我不太擅长基准测试,所以如果我有任何错误,请纠正我。
这是我的主类的代码:
这意味着,每个方法运行枚举长度的 50000 倍
我多次运行此测试,使用 10、20、50 和 100 个枚举常量。
结果如下:
这些结果并不准确。 再次执行时,结果有高达 10% 的差异,但它们足以表明,try/catch 方法的效率要低得多,尤其是对于小枚举。
Most of the answers suggest either using a loop with equals to check if the enum exists or using try/catch with enum.valueOf(). I wanted to know which method is faster and tried it. I am not very good at benchmarking, so please correct me if I made any mistakes.
Heres the code of my main class:
This means, each methods run 50000 times the lenght of the enum
I ran this test multiple times, with 10, 20, 50 and 100 enum constants.
Here are the results:
These results were not exact. When executing it again, there is up to 10% difference in the results, but they are enough to show, that the try/catch method is far less efficient, especially with small enums.
从 Java 8 开始,我们可以使用 流 而不是 for 循环。 另外,返回 Optional 可能是合适的 如果枚举没有具有此类名称的实例。
关于如何查找枚举,我提出了以下三种替代方案:
Since Java 8, we could use streams instead of for loops. Also, it might be apropriate to return an Optional if the enum does not have an instance with such a name.
I have come up with the following three alternatives on how to look up an enum:
只需使用
valueOf()
方法即可。如果该值不存在,它会抛出
IllegalArgumentException
并且您可以像这样catch
它:Just use
valueOf()
method.If the value doesn't exist, it throws
IllegalArgumentException
and you cancatch
it like that:您还可以使用 Guava 并执行以下操作:
在第二种方法中,我使用 guava (Google Guava)库提供了非常有用的Iterables类。 使用 Iterables.any() 方法我们可以检查给定值是否存在于列表对象中。 该方法需要两个参数:一个列表和Predicate对象。 首先,我使用 Arrays.asList() 方法创建一个包含所有枚举的列表。 之后,我创建了新的 Predicate 对象,用于检查给定元素(在我们的例子中为枚举)是否满足 apply 方法中的条件。 如果发生这种情况,方法 Iterables.any() 返回 true 值。
You can also use Guava and do something like this:
In second method I use guava (Google Guava) library which provides very useful Iterables class. Using the Iterables.any() method we can check if a given value exists in a list object. This method needs two parameters: a list and Predicate object. First I used Arrays.asList() method to create a list with all enums. After that I created new Predicate object which is used to check if a given element (enum in our case) satisfies the condition in apply method. If that happens, method Iterables.any() returns true value.
使用 java 8,您可以执行如下操作来检查它是否有效。
Using java 8, you can do something like the below to check if it is valid.
这是我用来检查给定名称的枚举常量是否存在的方法:(
假设您的枚举称为 E。)在“”内,您应该放置一个枚举常量的名称,您希望检查它是否在枚举与否。
这当然不是最好的解决方案,因为它将数组转换为 Stream,然后再次转换为 List,但它很好,很短,对我来说效果很好。
正如其他人提到的,自从您在 2009 年提出这个问题以来,自 2009 年以来这对您的情况不起作用(除非您迁移到较新版本的 Java)。Java 不支持此答案中使用的功能。 但无论如何我都会发帖,以防使用较新版本 Java 的人想要这样做。
Here is what I use to check if an enum constant with given name exists:
(Suppose your enum is called E.) Here inside "" you should put a name of an enum constant for which you wish to check if it is defined in the enum or not.
This is certainly not the best possible solution since it converts an array into Stream and then again into List, but is nice and short and it works fine for me.
As other people mentioned, since you asked this question in 2009., this will not work in your case (unless you migrated to a newer version of Java) since in 2009. Java did not support features used in this answer. But I am posting anyway in case someone with newer version of Java wants to do this.