Java枚举自动生成getInstance方法?
假设我有以下java枚举Java枚举自动生成getInstance方法?,java,intellij-idea,enums,auto-generate,Java,Intellij Idea,Enums,Auto Generate,假设我有以下java枚举 public enum Color { RED(10), GREEN(22), BLUE(33); private int value; Color(int value) { this.value = value; } public int intValue() { return value; } } 为了能够通过给定的整数值获得颜色实例,我需要添加如下方法: public static Color getInst
public enum Color {
RED(10),
GREEN(22),
BLUE(33);
private int value;
Color(int value) {
this.value = value;
}
public int intValue() {
return value;
}
}
为了能够通过给定的整数值获得颜色实例,我需要添加如下方法:
public static Color getInstance(int value) {
switch (value) {
case 10: return RED;
case 22: return GREEN;
case 33: return BLUE;
default: throw new IllegalArgumentException("Invalid color value");
}
}
是否可以从IDE自动生成此方法?(最好是IntelliJ)如果您使用的是Java 8,您可以使用
接口中的默认方法向任何类添加功能,甚至枚举
看看我在枚举
中添加反向查找的地方,只需使其实现反向查找
,而不是在每个枚举
中重复代码,就可以使用int
值为所有类型的枚举实现一个中央实用程序方法。这是可能的,因为enum
s可以实现接口,因此您可以定义访问int
值的统一方式:
public interface IntValued {
int intValue();
}
/** get the particular {@link IntValued} {@code enum} constant. */
public static <T extends Enum<T>&IntValued> T get(Class<T> type, int value) {
return type.cast(GET.get(type).apply(value));
}
private static ClassValue<IntFunction<Enum>> GET = new ClassValue<IntFunction<Enum>>() {
protected IntFunction<Enum> computeValue(Class<?> type) {
return prepare(type);
}
};
// invoked only once per enum type
static IntFunction<Enum> prepare(Class<?> type) {
Enum[] values=type.asSubclass(Enum.class).getEnumConstants();
if(values.length==0) return i -> null;
IntSummaryStatistics s=Arrays.stream(values)
.mapToInt(o -> ((IntValued)o).intValue())
.summaryStatistics();
int min=s.getMin(), max=s.getMax();
if((max-min+1)<s.getCount()*2) {
Enum[] linear=new Enum[max-min+1];
for(Enum e: values) linear[((IntValued)e).intValue()-min]=e;
return i -> i<min||i>max? null: linear[i-min];
}
Map<Integer, Enum> map = Arrays.stream(values).collect(
Collectors.toMap(o -> ((IntValued)o).intValue(), Function.identity()));
return map::get;
}
请注意,与生成的switch
语句不同,如果这些int值发生更改,此解决方案不会中断。您希望在您的一生中编写多少这样的enum
s?我在一个项目中工作,其中引入的许多enum中包含的值远远超过三个。手工编码这些东西真是浪费时间。看在上帝的份上,使用通用色码吧。它将使您的生活以及开发人员(他们将在您之后)变得更加轻松。这样,你就不用处理枚举了。@WeareBorg完全同意:)太好了!我相信是您不久前向我指出,Class
有一个cast
方法<代码>返回类型.cast(GET.GET(type).apply(value))代码>可以避免邪恶的施法。@OldCurmudgeon:你说得对;在这里,Netbeans在默认配置中不会生成所有未检查的警告,这似乎是不必要的复杂。为什么不仅仅是一个带有签名的静态方法,比如publicstaticmappyvalue(Collection values)
,它的主体是您的倒数第二条语句?它甚至不需要特定于枚举类型。@VGR:关键是每次调用get
方法时,此代码都不会填充映射。对于具体的enum
,它最多只能执行一次,但是,如前所述,如果int
值密集,它甚至可以使用更快的基于数组的访问器。每个后续调用都将重用第一次调用时创建的访问器函数。我们的目标是要和问题的开关语句一样快。@VGR:这是问题的前提。如果你看看那里的评论,我已经问过了,这些enum
类型中有多少是预期的。此解决方案用于OP的假设,即该数字非常大,因此每个enum
自动生成的代码是合理的。因此,我提供了一个解决方案,消除了对每个<代码> EnUM<代码>类型添加代码的需要,但与原来的<代码>开关解决方案的性能( TabLSwitCH 对于密集数和 LoopUpSwite)是一致的。对于每个类型的映射不会有太多问题,但是这个解决方案也可以避免每次调用都有映射。
public enum Color implements IntValued {
RED(10),
GREEN(22),
BLUE(33);
private int value;
Color(int value) {
this.value = value;
}
public int intValue() {
return value;
}
}
Color color=get(Color.class, 22);
System.out.println(color);