Java Enum用条件初始化

Sta*_*tan 4 java enums

在某些情况下,我想用以下值初始化我的枚举Foo.

private enum Foo {
  BAR1("1"),
  BAR2("2"),
  BAR3("3")
}
Run Code Online (Sandbox Code Playgroud)

在其他一些情况下,我想要一组不同的值.

private enum Foo {
  BAR1("x"),
  BAR2("y"),
  BAR3("z")
}
Run Code Online (Sandbox Code Playgroud)

然后在其他代码中,它可以使用相同的枚举进行处理.我怎样才能做到这一点?或者还有其他更好的方法来实现我的目标吗?

And*_*ner 7

您可以在枚举初始值设定项中包含多个值,然后使用逻辑来选择适当的值:

enum Foo {
  BAR1("1", "x"),
  BAR2("2", "y"),
  BAR3("3", "z");

  private final String first, second;

  private Foo(String first, String second) {
    this.first = first; this.second = second;
  }

  String value(boolean condition) {
    return condition ? first : second;
  }
}
Run Code Online (Sandbox Code Playgroud)


And*_*ner 1

我将其添加为第二个答案,而不是更新我现有的答案,因为我认为它与人们已经投票的答案有太大不同。

将选项保留在类内部的另一种方法是在外部定义映射。如果您希望能够支持两个以上的映射,这可能是一个更好的选择。

这样做的优点是您可以定义对代码的特定位私有的新映射:添加新用例时无需更改枚举的定义。

例如:

EnumMap<Foo, String> numberEnumMapping = new EnumMap<>(Foo.class);
numberEnumMapping.put(Foo.BAR1, "1");
numberEnumMapping.put(Foo.BAR2, "2");
numberEnumMapping.put(Foo.BAR3, "3");
Map<Foo, String> numberMapping = Collections.unmodifiableMap(numberEnumMapping);

EnumMap<Foo, String> letterEnumMapping = new EnumMap<>(Foo.class);
letterEnumMapping.put(Foo.BAR1, "x");
letterEnumMapping.put(Foo.BAR2, "y");
letterEnumMapping.put(Foo.BAR3, "z");
Map<Foo, String> letterMapping = Collections.unmodifiableMap(letterEnumMapping);

// ... More mappings.
Run Code Online (Sandbox Code Playgroud)

(我个人会为此使用 Guava ImmutableMap,但您可能不想使用 Guava)。

然后您可以将 传递Map<Foo, String>到需要执行映射的位置:

void doSomething(Foo value, Map<Foo, String> mapping) {
  System.out.println(mapping.get(value));
}
Run Code Online (Sandbox Code Playgroud)

如果您认为更简洁,您可以定义一个接口而不是使用 Map:

interface FooStrategy {
  String get(Foo value);
}
Run Code Online (Sandbox Code Playgroud)

但想法是相同的:将 传递FooStrategy到需要将 a 转换Foo为 a 的地方String。

void doSomething(Foo value, FooStrategy mapping) {
  System.out.println(mapping.get(value));
}
Run Code Online (Sandbox Code Playgroud)