Java 多个枚举具有相同的功能?
我想创建一些枚举,如本答案中所述: (即具有toString()和与枚举本身不同的名称的枚举)Java 多个枚举具有相同的功能?,java,enums,Java,Enums,我想创建一些枚举,如本答案中所述: (即具有toString()和与枚举本身不同的名称的枚举) 有没有什么方法可以在不必在每个枚举中重新实现的情况下重用此功能?我认为您无法摆脱在每个枚举中“添加字段和属性”的困扰。如果为该属性创建接口,并传递values()或(更好)一个EnumSet,则可以将fromText方法委托给公共方法。(更好的方法是:编写一个方法来创建一个不区分大小写的映射,并在每个枚举中调用该映射一次,将结果存储在一个静态变量中。)我认为您无法摆脱在每个枚举中“添加字段和属性”的
有没有什么方法可以在不必在每个枚举中重新实现的情况下重用此功能?我认为您无法摆脱在每个枚举中“添加字段和属性”的困扰。如果为该属性创建接口,并传递
values()
或(更好)一个EnumSet
,则可以将fromText
方法委托给公共方法。(更好的方法是:编写一个方法来创建一个不区分大小写的映射,并在每个枚举中调用该映射一次,将结果存储在一个静态变量中。)我认为您无法摆脱在每个枚举中“添加字段和属性”的问题。如果为该属性创建接口,并传递values()
或(更好)一个EnumSet
,则可以将fromText
方法委托给公共方法。(更好的方法是:编写一个方法来创建一个不区分大小写的映射,并在每个枚举中调用一次,将结果存储在一个静态变量中。)如果有许多枚举共享相同的功能,我也会这样做
- 使用一个枚举,因为它们有很多共同点
- 使用每个枚举可以调用的帮助器方法
Java8将通过虚拟扩展简化这一过程。它将允许您在接口上定义一个默认实现(必须是一个helper/静态方法)如果您有许多枚举,它们共享与我相同的功能
- 使用一个枚举,因为它们有很多共同点
- 使用每个枚举可以调用的帮助器方法
Java8将通过虚拟扩展简化这一过程。它将允许您在接口上定义一个默认实现(必须是一个帮助器/静态方法)如果您传入可能的值列表,那么您可以不依赖于枚举的类型来执行它
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.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);
}
};
}
[...]
事实上,您可能希望对此进行优化。执行toString
ing一次,然后使用地图
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;
}
};
}
publicstaticbystring ByString(T[]值){
最终映射ByToString=新HashMap(
(int)(values.length/0.75f)+1//不会让HashMap构造变得糟糕。
);
对于(T值:值){
bytoString.put(values.toString(),value);
}
返回新的ByString(){
公共找不到(字符串到字符串){
T值=bytoString.get(toString);
如果(值==null){
抛出新的IllegalArgumentException();
}
返回值;
}
};
}
如果传入可能值的列表,则无需依赖于枚举的类型即可执行此操作
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.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);
}
};
}
[...]
事实上,您可能希望对此进行优化。执行toString
ing一次,然后使用地图
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;
}
};
}
publicstaticbystring ByString(T[]值){
最终映射ByToString=新HashMap(
(int)(values.length/0.75f)+1//不会让HashMap构造变得糟糕。
);
对于(T值:值){
bytoString.put(values.toString(),value);
}
返回新的ByString(){
公共找不到(字符串到字符串){
T值=bytoString.get(toString);
如果(值==null){
抛出新的IllegalArgumentException();
}
返回值;
}
};
}
认为完全删除“命名”枚举可能更简单!谢谢你的回答。我想完全去掉“命名”枚举可能更简单!谢谢你的回答。