我想创建一些枚举,如本答案中所述: Lookup enum by string value
(即,一个包含toString()的枚举和一个与枚举本身不同的名称)
有什么办法可以重用这个功能,而不必在每个枚举中重新实现它?
答案 0 :(得分:3)
我不相信你可以在每个枚举中摆脱“添加字段和属性”。您可以将fromText
方法委托给一个常用方法,如果您为该属性创建一个接口,并传递values()
或(更好)EnumSet
。 (更好:编写一个方法来创建不区分大小写的Map
,并在每个枚举中调用一次,将结果存储在静态变量中。)
答案 1 :(得分:3)
如果您传入可能值列表,那么您可以在不依赖于enum
类型的情况下执行此操作。
public static <T> T findByString(T[] values, String toString) {
Objects.requireNonNull(toString);
for (T t : values) {
if (toString.equals(t.toString())) {
return t;
}
}
throw new IllegalArgumentException();
}
致电:
Blah blah = SomeClass.findByString(Blah.values(), str);
不是每次调用Blah.values()
,而是可以将它放在一个对象中,该对象可以传递并一般使用。也许以后会添加其他方法。
public interface ByString<T> { // Choose a better name.
T find(String toString);
}
[...]
private static final ByString<Blah> blahs = byString(Blah.values());
[...]
public static <T> ByString<T> byString(T[] values) {
final T[] valuesCopy = values.clone();
return new ByString<T>() {
public T find(String toString) {
return SomeClass.findByString(valuesCopy, toString);
}
};
}
[...]
致电:
Blah blah = blahs.find(str);
事实上,您可能希望优化它。执行toString
一次,然后使用地图。
public static <T> ByString<T> byString(T[] values) {
final Map<String,T> byToStrings = new HashMap<>(
(int)(values.length/0.75f)+1 // Doesn't HashMap construction suck.
);
for (T value : values) {
byToStrings.put(values.toString(), value);
}
return new ByString<T>() {
public T find(String toString) {
T value = byToStrings.get(toString);
if (value == null) {
throw new IllegalArgumentException();
}
return value;
}
};
}
答案 2 :(得分:1)
如果您有许多共享相同功能的枚举,我会。
Java 8将使虚拟扩展更简单。它允许您在接口上定义默认实现(必须是辅助/静态方法)