Java:检查enum是否包含给定的字符串?

这是我的问题-我正在寻找(如果它甚至存在)等价于ArrayList.contains();的enum。

下面是我的代码问题示例:

enum choices {a1, a2, b1, b2};


if(choices.???(a1)}{
//do this
}

现在,我意识到StringsArrayList在这里是更好的路径,但我必须通过其他地方的switch/case运行枚举内容。这就是我的问题所在。

假设这样的东西不存在,我该怎么做呢?

467223 次浏览

enum在Java中非常强大。你可以很容易地将contains方法添加到枚举中(就像将方法添加到类中一样):

enum choices {
a1, a2, b1, b2;


public boolean contains(String s)
{
if (s.equals("a1") || s.equals("a2") || s.equals("b1") || s.equals("b2"))
return true;
return false;
}


};

我不认为有,但你可以这样做:

enum choices {a1, a2, b1, b2};


public static boolean exists(choices choice) {
for(choice aChoice : choices.values()) {
if(aChoice == choice) {
return true;
}
}
return false;
}

编辑:

请参阅Richard的版本,因为它更合适,因为这不会工作,除非你将它转换为使用字符串,Richards这样做。

你可以使用Enum.valueOf()

enum Choices{A1, A2, B1, B2};


public class MainClass {
public static void main(String args[]) {
Choices day;


try {
day = Choices.valueOf("A1");
//yes
} catch (IllegalArgumentException ex) {
//nope
}
}

如果你希望检查经常失败,你可能会更好地使用一个简单的循环,就像其他人展示的那样——如果你的枚举包含许多值,也许会构建HashSet或类似的枚举值转换为字符串并查询HashSet

如果你想通过String查找,可以使用valueOf("a1")

这应该做到:

public static boolean contains(String test) {


for (Choice c : Choice.values()) {
if (c.name().equals(test)) {
return true;
}
}


return false;
}

这种方式意味着你不必担心以后添加额外的enum值,它们都是被检查的。

编辑:如果枚举非常大,你可以将值放在HashSet中:

public static HashSet<String> getEnums() {


HashSet<String> values = new HashSet<String>();


for (Choice c : Choice.values()) {
values.add(c.name());
}


return values;
}

然后你可以这样做:values.contains("your string"),返回true或false。

它是一个枚举,这些都是常量值,所以如果它在switch语句中,它就像这样做:

case: val1
case: val2

还有,为什么你需要知道什么被声明为常数?

更好的是:

enum choices {
a1, a2, b1, b2;


public static boolean contains(String s)
{
for(choices choice:values())
if (choice.name().equals(s))
return true;
return false;
}


};

为什么不将Pablo的回复与valueOf()结合起来呢?

public enum Choices
{
a1, a2, b1, b2;


public static boolean contains(String s) {
try {
Choices.valueOf(s);
return true;
} catch (Exception e) {
return false;
}
}
public boolean contains(Choices value) {
return EnumSet.allOf(Choices.class).contains(value);
}

用番石榴就更简单了:

boolean isPartOfMyEnum(String myString){


return Lists.newArrayList(MyEnum.values().toString()).contains(myString);


}

这结合了以前方法中的所有方法,应该具有相同的性能。它可以用于任何枚举,内联“编辑”解决方案从@Richard H,并使用例外的无效值,如@bestsss。唯一的折衷是需要指定类,但这将把它变成一个两行代码。

import java.util.EnumSet;


public class HelloWorld {


static enum Choices {a1, a2, b1, b2}


public static <E extends Enum<E>> boolean contains(Class<E> _enumClass, String value) {
try {
return EnumSet.allOf(_enumClass).contains(Enum.valueOf(_enumClass, value));
} catch (Exception e) {
return false;
}
}


public static void main(String[] args) {
for (String value : new String[] {"a1", "a3", null}) {
System.out.println(contains(Choices.class, value));
}
}

请使用Apache commons lang3库

 EnumUtils.isValidEnum(MyEnum.class, myValue)

你可以用这个

YourEnum {A1, A2, B1, B2}

boolean contains(String str){
return Sets.newHashSet(YourEnum.values()).contains(str);
}

@wightwulf1944建议的更新被纳入,使解决方案更有效。

番石榴枚举可以是你的朋友

比如这个:

enum MyData {
ONE,
TWO
}


@Test
public void test() {


if (!Enums.getIfPresent(MyData.class, "THREE").isPresent()) {
System.out.println("THREE is not here");
}
}
com.google.common.collect.Sets.newHashSet(MyEnum.values()).contains("myValue")
< br > < p >几个假设: 1)没有try/catch,因为它是例外的流控制
2)` contains `方法必须是快速的,因为它通常运行几次 3)空间不受限制(普通解常见)

import java.util.HashSet;
import java.util.Set;


enum Choices {
a1, a2, b1, b2;


private static Set<String> _values = new HashSet<>();


// O(n) - runs once
static{
for (Choices choice : Choices.values()) {
_values.add(choice.name());
}
}


// O(1) - runs several times
public static boolean contains(String value){
return _values.contains(value);
}
}

如果你使用的是Java 1.8,你可以选择Stream + Lambda来实现:

public enum Period {
DAILY, WEEKLY
};


//This is recommended
Arrays.stream(Period.values()).anyMatch((t) -> t.name().equals("DAILY1"));
//May throw java.lang.IllegalArgumentException
Arrays.stream(Period.values()).anyMatch(Period.valueOf("DAILY")::equals);

您可以先将枚举转换为List,然后使用List contains方法

enum Choices{A1, A2, B1, B2};


List choices = Arrays.asList(Choices.values());


//compare with enum value
if(choices.contains(Choices.A1)){
//do something
}


//compare with String value
if(choices.contains(Choices.valueOf("A1"))){
//do something
}

此方法可用于检查任何Enum,你可以将它添加到Utils类中:

public static <T extends Enum<T>> boolean enumContains(Class<T> enumerator, String value)
{
for (T c : enumerator.getEnumConstants()) {
if (c.name().equals(value)) {
return true;
}
}
return false;
}

可以这样用:

boolean isContained = Utils.enumContains(choices.class, "value");

解决方案,检查值是否存在,以及获得enum值返回:

protected TradeType getEnumType(String tradeType) {
if (tradeType != null) {
if (EnumUtils.isValidEnum(TradeType.class, tradeType)) {
return TradeType.valueOf(tradeType);
}
}
return null;
}

这里已经提到了几个库,但是我错过了我真正要找的一个:Spring!

ObjectUtils # containsConstant默认情况下是不区分大小写的,但如果你愿意,也可以很严格。它是这样使用的:

if(ObjectUtils.containsConstant(Choices.values(), "SOME_CHOISE", true)){
// do stuff
}

注意:我在这里使用重载方法是为了演示如何使用区分大小写的检查。您可以省略布尔值以具有不区分大小写的行为。

但是要小心使用大的枚举,因为他们不像一些人那样使用Map实现…

作为奖励,它还提供了valueOf: ObjectUtils # caseInsensitiveValueOf的不区分大小写的变体

这个对我很有用:

Arrays.asList(YourEnum.values()).toString().contains("valueToCheck");

我为这个验证创建了下一个类

public class EnumUtils {


public static boolean isPresent(Enum enumArray[], String name) {
for (Enum element: enumArray ) {
if(element.toString().equals(name))
return true;
}
return false;
}


}

用法示例:

public ArrivalEnum findArrivalEnum(String name) {


if (!EnumUtils.isPresent(ArrivalEnum.values(), name))
throw new EnumConstantNotPresentException(ArrivalEnum.class,"Arrival value must be 'FROM_AIRPORT' or 'TO_AIRPORT' ");


return ArrivalEnum.valueOf(name);
}

如果你使用的是Java 8或以上版本,你可以这样做:

boolean isPresent(String testString){
return Stream.of(Choices.values()).map(Enum::name).collect(Collectors.toSet()).contains(testString);
}
  Set.of(CustomType.values())
.contains(customTypevalue)

Java Streams提供了一种优雅的方式来做到这一点

Stream.of(MyEnum.values()).anyMatch(v -> v.name().equals(strValue))
< p >的回报: 如果流中的任何元素匹配提供的值,则为True,否则为false

你可以把它作为一个contains方法:

enum choices {a1, a2, b1, b2};
public boolean contains(String value){
try{
EnumSet.allOf(choices.class).contains(Enum.valueOf(choices.class, value));
return true;
}catch (Exception e) {
return false;
}
}


或者你可以在代码块中使用它:

try{
EnumSet.allOf(choices.class).contains(Enum.valueOf(choices.class, "a1"));
//do something
}catch (Exception e) {
//do something else
}


你也可以使用:com.google.common.base.Enums

enumes . getifpresent (varEnum.class, varToLookFor)返回一个Optional

enumel . getifpresent (fooenumel .class, myVariable).isPresent() ? Enums.getIfPresent (fooEnum.class myVariable)。get: fooEnum。其他< / p >

我会写,

Arrays.stream(Choice.values()).map(Enum::name).collect(Collectors.toList()).contains("a1");

Enum#equals只适用于对象比较。

如果你想导入Apache commons lang3, EnumUtils.isValidEnum可能是最好的选择。如果不是下面是一个通用函数,我会用作替代。

private <T extends Enum<T>> boolean enumValueExists(Class<T> enumType, String value) {
boolean result;
try {
Enum.valueOf(enumType, value);
result = true;
} catch (IllegalArgumentException e) {
result = false;
}
return result;
}


然后像下面这样使用

if (enumValueExists(MyEnum.class, configValue)) {
// happy code
} else {
// angry code
}

虽然迭代一个列表或捕捉一个异常对于大多数情况来说已经足够好了,但我正在寻找一些可重用的东西,这些东西对于大型枚举来说也很好。最后,我写下了这样一段话:

public class EnumValidator {


private final Set<String> values;


private EnumValidator(Set<String> values) {
this.values = values;
}


public static <T extends Enum<T>> EnumValidator of(Class<T> enumType){
return new EnumValidator(Stream.of(enumType.getEnumConstants()).map(Enum::name).collect(Collectors.toSet()));
}


public boolean isPresent(String et){
return values.contains(et);
}
    

}

Java 8+流+设置方式:

    // Build the set.
final Set<String> mySet = Arrays//
.stream(YourEnumHere.values())//
.map(Enum::name)//
.collect(Collectors.toSet());


// Reuse the set for contains multiple times.
mySet.contains(textA);
mySet.contains(textB);
...