使用'valueOf'检索枚举会抛出RuntimeException - 要使用什么?

Joe*_*dev 11 java enums

我有以下枚举

enum Animal implements Mammal {
   CAT, DOG;

   public static Mammal findMammal(final String type) {
      for (Animal a : Animal.values()) {
         if (a.name().equals(type)) {
            return a;
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

我最初用它Enum.valueOf(Animal.class, "DOG");来找到一个特定的动物.但是,我没有意识到如果找不到匹配,IllegalArgumentException则抛出一个.我以为可能会返回null.所以这给我一个问题.IllegalArgumentException如果找不到匹配,我不想抓住这个.我希望能够搜索所有类型的枚举,Mammal我不想findMammal为每个类型的枚举实现这个静态' ' Mammal.所以我的问题是,实现这种行为的最吉祥的设计决定是什么?我将调用这样的代码:

public class Foo {
   public Mammal bar(final String arg) {
      Mammal m = null;
      if (arg.equals("SomeValue")) {
         m = Animal.findMammal("CAT");
      } else if (arg.equals("AnotherValue") {
         m = Human.findMammal("BILL");
      }
      // ... etc
   }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我有不同类型的哺乳动物 - "动物","人类",它们都是枚举.我不想为每个Mammal枚举实现'findMammal'.我想最好的选择就是创建一个实用程序类,它接受一个Mammal参数并进行搜索?也许有一个更整洁的解决方案.

Jon*_*eet 12

如何创建一个HashMap<String, Mammal>?你只需要做一次......

public class Foo {

  private static final Map<String, Mammal> NAME_TO_MAMMAL_MAP;

  static {
    NAME_TO_MAMMAL_MAP = new HashMap<String, Mammal>();
    for (Human human : EnumSet.allOf(Human.class)) {
      NAME_TO_MAMMAL_MAP.put(human.name(), human);
    }
    for (Animal animal : EnumSet.allOf(Animal.class)) {
      NAME_TO_MAMMAL_MAP.put(animal.name(), animal);
    }
  }

  public static Mammal bar(final String arg) {
    return NAME_TO_MAMMAL_MAP.get(arg);
  }
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • null如果名称不存在,则返回
  • 这不会检测到名称冲突
  • 您可能想要使用某些描述的不可变映射(例如通过Guava)
  • 您可能希望编写一个实用程序方法来为常规枚举创建不可变的名称到值的映射,然后只合并映射:)


Dmi*_*tri 9

如果您不想触及每个Enum(可理解),那么实用方法就是您的选择.我理解不想在你的代码中捕获异常,但在方法中捕获它应该没问题,但是:

public static <T extends Enum<T>> T findEnumValue(Class<T> type, String name) {
    if (name == null)
        return null;
    try {
        return Enum.valueOf(type, name.toUpperCase());
    } catch (IllegalArgumentException iae) {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你真的不想捕获运行时异常(看起来很随意,说实话),你总是可以搜索值,或者使用支持地图 - 类似于Jon的答案,但是自动填充而不仅限于动物枚举. (4认同)

fee*_*.me 9

您可以使用apache EnumUtils库中的getEnum方法.它返回枚举或未找到.null

EnumUtils.getEnum(Animal.class, "CAT");
Run Code Online (Sandbox Code Playgroud)


And*_*lis 8

你可以使用番石榴库.枚举类允许这样:

Enums.valueOfFunction(MyEnum.class).apply(id);
Run Code Online (Sandbox Code Playgroud)

  • 似乎已删除,可能有利于'Enums.getIfPresent(Country.class,countryInput).or(Country.DEFAULT);`,这很好.链接仍然可以. (3认同)