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

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

枚举:

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; } } 

获得一个新的枚举:

 aStringRecivedFromJson = "Anti Social Behaviour" CrimeCategory crimeCategoryEnum; crimeCategoryEnum = CrimeCategory.valueOf(aStringRecivedFromJson); 

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

预期成果: ASBO

作为参考,这是一个使用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 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; } } 

将一个静态方法添加到CrimeCategory枚举:

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

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

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

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

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

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

 interface Matchable { Object getField(); public static  & Matchable> E forToken(Class 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())); } } 

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

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