我可以根据其字段的值获得枚举吗?

Jet*_*hro 21 java string enums

我想根据其字段值获取特定的枚举.

枚举:

public enum CrimeCategory {
    ASBO ("Anti Social Behaviour"),
    BURG ("Burglary"),
    CRIMDAM ("Criminal Damage And Arson"),
    DRUGS ("Drugs"),
    OTHTHEFT ("Other Theft"),
    PUPDISOR ("Public Disorder And Weapons"),
    ROBBERY ("Robbery"),
    SHOPLIF ("Shoplifting"),
    VEHICLE ("Vehicle Crime"),
    VIOLENT ("Violent Crime"),
    OTHER ("Other Crime");

    private  String category;


    private CrimeCategory (String category) {
        this.category = category;
    }

    public String returnString() {
        return category; 
    }
}
Run Code Online (Sandbox Code Playgroud)


获得一个新的枚举:

aStringRecivedFromJson = "Anti Social Behaviour"
CrimeCategory crimeCategoryEnum;
crimeCategoryEnum = CrimeCategory.valueOf(aStringRecivedFromJson); 
Run Code Online (Sandbox Code Playgroud)

我一直试图找到一种方法,以便上面带回一个枚举,以便它可以传递存储在HashMap其他Crime信息中.

预期结果: ASBO

ass*_*ias 30

作为参考,这是一个使用HashMap的替代解决方案:

enum CrimeCategory {
  ASBO("Anti Social Behaviour"),
  BURG("Burglary"),
  CRIMDAM("Criminal Damage And Arson"),
  DRUGS("Drugs"),
  OTHTHEFT("Other Theft"),
  PUPDISOR("Public Disorder And Weapons"),
  ROBBERY("Robbery"),
  SHOPLIF("Shoplifting"),
  VEHICLE("Vehicle Crime"),
  VIOLENT("Violent Crime"),
  OTHER("Other Crime");

  private static final Map<String, CrimeCategory> map = new HashMap<>(values().length, 1);

  static {
    for (CrimeCategory c : values()) map.put(c.category, c);
  }

  private final String category;

  private CrimeCategory(String category) {
    this.category = category;
  }

  public static CrimeCategory of(String name) {
    CrimeCategory result = map.get(name);
    if (result == null) {
      throw new IllegalArgumentException("Invalid category name: " + name);
    }
    return result;
  }
}
Run Code Online (Sandbox Code Playgroud)


sha*_*kan 24

CrimeCategory枚举中添加静态方法:

public static CrimeCategory valueOf(String name) {
    for (CrimeCategory category : values()) {
        if (category.category.equals(name)) {
            return category;
        }
    }    
    throw new IllegalArgumentException(name);
}
Run Code Online (Sandbox Code Playgroud)

  • 或者如果性能很关键,可以使用包含映射的静态HashMap ...... (5认同)

sco*_*ttb 5

基于实例字段的值返回枚举常量的静态工厂方法采用其他答案中描述的两种形式之一:基于迭代枚举值的解决方案,或基于HashMap.

对于具有少量常量的枚举,迭代解决方案应该与解决HashMap方案(需要计算哈希码,将其与桶匹配,并假设不会发生哈希冲突)一样高效。

对于较大的枚举,基于映射的解决方案将具有更高的性能(但需要内存中的存储空间)。但是,如果不经常调用工厂方法,那么使用映射带来的整体性能改进仍然小得不可估量。

对静态工厂方法使用迭代查找或基于映射的查找的总体决定最终取决于您的要求和环境。如果分析显示实际的性能问题,从迭代查找开始然后更改为基于映射的实现永远不会错。

最后,自 Java 8 以来,StreamsAPI 支持基于管道的映射解决方案(其性能应与迭代解决方案类似)。例如,假设您想要创建一个可以在任何枚举类上使用的接口,以表达您的意图:它应该与其实例字段之一匹配。我们称这个接口为Matchable。该接口定义了一个方法,该方法返回要匹配的实例字段(例如getField())。该接口还可以定义静态工厂方法以从任何实现枚举类返回常量:

interface Matchable {

    Object getField();

    public static <E extends Enum<E> & Matchable> E forToken(Class<E> cls, Object token) {

        return Stream.of(cls.getEnumConstants())
            .filter(e -> e.getField().equals(token))
            .findFirst()
            .orElseThrow(() -> new IllegalArgumentException("Unknown token '" +
                    token + "' for enum " + cls.getName()));
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您定义的任何实现的枚举类都Matchable可以使用Matchable.forToken()静态工厂方法来查找其实例字段值与提供的参数匹配的枚举常量。

泛型类型声明E extends Enum<E> & Matchable确保作为参数传递给方法的类型标记将用于实现的枚举类Matchable(否则代码将无法编译)。