Java 枚举:将字符串转换为枚举
我可以知道如何将字符串“male”转换为任何枚举吗?是,该值与枚举不同。这行不通Java 枚举:将字符串转换为枚举,java,enums,Java,Enums,我可以知道如何将字符串“male”转换为任何枚举吗?是,该值与枚举不同。这行不通 public enum Gender{ m("male"), f("female"); private final String value; private Gender(String option){ value = option; } } 我在考虑提供一个 1) 使用for循环进行解析 或 2) 静态初始化映射 我觉得第二种方法更好,因为当我初始化
public enum Gender{
m("male"), f("female");
private final String value;
private Gender(String option){
value = option;
}
}
我在考虑提供一个
1) 使用for循环进行解析
或
2) 静态初始化映射
我觉得第二种方法更好,因为当我初始化映射时,如果存在相同的字符串,我可以抛出运行时异常
优点和缺点是什么?或者还有其他更好的解决方案吗?我会使用地图:
Gender.valueOf("male");
公共枚举性别{
男(“男”),女(“女”);
私有最终字符串值;
私有静态最终映射值=新HashMap();
静止的{
for(Gender g:Gender.values()){
if(value.put(g.value,g)!=null){
抛出新的IllegalArgumentException(“重复值:+g.value”);
}
}
}
私人性别(字符串选项){
价值=期权;
}
公共静态性别fromString(字符串选项){
返回值.get(选项);
}
}
我认为这比第一种方法有两个优点:
public enum Gender {
m("male"), f("female");
private final String value;
private static final Map<String, Gender> values = new HashMap<String, Gender>();
static {
for (Gender g : Gender.values()) {
if (values.put(g.value, g) != null) {
throw new IllegalArgumentException("duplicate value: " + g.value);
}
}
}
private Gender(String option) {
value = option;
}
public static Gender fromString(String option) {
return values.get(option);
}
}
O(1)
time中将字符串转换为Gender
,而另一种方法需要O(n)
time我曾多次遇到这种情况,通常使用您的第一种方法:
public enum Gender {
m("male"), f("female");
private final String value;
private static final Map<String, Gender> values = new HashMap<String, Gender>();
static {
for (Gender g : Gender.values()) {
if (values.put(g.value, g) != null) {
throw new IllegalArgumentException("duplicate value: " + g.value);
}
}
}
private Gender(String option) {
value = option;
}
public static Gender fromString(String option) {
return values.get(option);
}
}
由于您的
值
是声明的final
,并且所有实例都需要从代码中声明,因此您始终要对值的唯一性负责,因此对我来说,这个问题几乎不存在。这是一个更普遍的解决方案。每当枚举映射到代码值时,我都会使用它。当一个枚举表示一系列离散值(例如映射到数据库表)时,它特别有用。请注意,接下来定义的几个类型只需编写一次,然后就可以在任何枚举上使用
首先定义枚举(或存储在集合中的POJO)将实现的接口:
public static Gender forValue(String value) {
for (Gender gender : gender.values()) {
if (gender.value.equals(value)) {
return gender;
}
}
return null; // or throw something like IllegalArgumentException
}
使用第二个选项更好,而且会被多次使用。为什么不使用Gender.valueOf(“m”)?因为这些值是在运行时初始化的。。m(常数.male())@NarendraPathai有什么例子吗?还是定义模式?我也这么觉得,只是想确认一下。嘿嘿哇,真不错!它看起来有点过度设计,但调用方的代码非常简单。无论如何,您还应该利用guava缓存,使其在O(1)而不是O(n)中运行
public final class CodedFinder {
private CodedFinder() {}
public static <V, T extends Enum<T> & Coded<V>> T find(final Class<T> target, final V code) {
final Optional<T> found = findInternal(Arrays.asList(target.getEnumConstants()), code);
if (! found.isPresent()) {
throw new IllegalArgumentException(code.toString() + " is invalid for " + target.getSimpleName());
}
return found.get();
}
// Additional find methods for arrays and iterables redacted for clarity.
private static <V, T extends Coded<V>> Optional<T> findInternal(final Iterable<T> values, final V code) {
return Iterables.tryFind(values, CodedPredicate.of(code));
}
}
public final class CodedPredicate<V, T extends Coded<V>> implements com.google.common.base.Predicate<T> {
private final V value;
private CodedPredicate(final V value) {
this.value = value;
}
public static <V, T extends Coded<V>> CodedPredicate<V, T> of(final V value) {
return new CodedPredicate<V, T>(value);
}
public boolean apply(final T current) {
return value.equals(current.getCode());
}
}
public final class GenderTest {
@Test(groups="unit")
public static void testValid() {
assert CodedFinder.find(Gender.class, "male") == Gender.m;
assert CodedFinder.find(Gender.class, "female") == Gender.f;
}
@Test(groups="unit", expectedExceptions=IllegalArgumentException.class)
public static void testInvalid() {
CodedFinder.find(Gender.class, "foo");
}
public enum Gender implements Coded<String> {
m("male"), f("female");
private final String value;
private Gender(final String option) {
value = option;
}
public String getCode()
{
return value;
}
}
}