Java枚举自动生成getInstance方法?

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

假设我有以下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 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);