我希望根据其字段值获得特定的枚举。
枚举:
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
答案 0 :(得分:27)
供参考,这是一个使用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;
}
}
答案 1 :(得分:20)
向CrimeCategory
枚举添加静态方法:
public static CrimeCategory valueOf(String name) {
for (CrimeCategory category : values()) {
if (category.category.equals(name)) {
return category;
}
}
throw new IllegalArgumentException(name);
}
答案 2 :(得分:2)
基于实例字段的值返回枚举常量的静态工厂方法采用其他答案中描述的两种形式之一:基于迭代枚举值的解决方案,或基于{{1的解决方案}}
对于具有少量常量的枚举,迭代解决方案应该与HashMap
解决方案一样高效(这需要计算哈希码,将其与存储桶匹配,并假设不存在哈希碰撞)。
对于较大的枚举,基于地图的解决方案将更具性能(但需要内存中的存储空间)。但是,如果不经常调用工厂方法,那么使用地图的整体性能提升仍然可能是无法估量的。
对静态工厂方法使用迭代查找或基于映射的查找的总体决策最终将取决于您的要求和环境。如果分析显示实际的性能问题,那么从迭代查找开始然后更改为基于地图的实现是绝对错误的。
最后,自Java 8以来,HashMap
API启用了基于管道的映射解决方案(其性能应与迭代解决方案类似)。例如,假设您要创建一个可以在任何枚举类上使用的接口,以表示您应该通过其中一个实例字段匹配的意图。让我们调用此接口Streams
。此接口定义一个方法,该方法返回您要匹配的实例字段(例如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()));
}
}
的枚举类都可以使用Matchable
静态工厂方法来查找其实例字段值与提供的参数匹配的枚举常量。
泛型类型声明Matchable.forToken()
确保作为参数传递给方法的类型标记将用于实现E extends Enum<E> & Matchable
的枚举类(否则代码将不会编译)。 / p>
答案 3 :(得分:1)
亚述人的回答很好。尽管我会从工厂方法返回一个Optional
来让客户端处理找不到枚举的情况(当然,如果您在内部使用此枚举,则抛出IllegalArgumentException
可能会更好用错误的参数调用此方法永远不会发生-这是您的选择。
我也将Map
包装到不可修改的包装中,以免意外在枚举内的某个地方对其进行修改(Map
是私有的,但是稍后有人可以在添加新功能时对其进行修改-它将在最少考虑的力量):
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;
static {
Map<String, CrimeCategory> crimeCategoryMap = Arrays.stream(values())
.collect(toMap(cg -> cg.category, e -> e));
MAP = Collections.unmodifiableMap(crimeCategoryMap);
}
private final String category;
private CrimeCategory(String category) {
this.category = category;
}
public static Optional<CrimeCategory> of(final String name) {
return Optional.ofNullable(MAP.get(name));
}
}