在某些情况下说我想用以下值初始化我的枚举Foo。
private enum Foo {
BAR1("1"),
BAR2("2"),
BAR3("3")
}
在其他一些情况下,我想要一组不同的值。
private enum Foo {
BAR1("x"),
BAR2("y"),
BAR3("z")
}
然后在其他代码中,它可以使用相同的枚举进行处理。我怎样才能做到这一点?或者还有其他更好的方法来实现我的目标吗?
答案 0 :(得分: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;
}
}
答案 1 :(得分:2)
编写另一个用可变部分包装不可变部分(你的枚举)的类(你的状态可以随时间变化)。
有点像这样:
enum Foo {
BAR1, BAR2
}
class StatefulFoo {
private Foo foo;
private String name;
public StatefulFoo(Foo foo, String name) {
this.foo = foo;
this.name = name;
}
public void setName(String name) {
this.name = name;
}
}
答案 2 :(得分:1)
由于我不允许发表评论,这里是@Andy的回答
我必须先说:枚举值可能会有所不同,这可能是由于设计不佳造成的。这是一种不好的做法,在多线程环境中,您可能需要在整个枚举中提供一致性等。
//Use this if your enum is system wide, and you make sure you can guarantee
//invariant -> length of array == length of enum.
static String [] sysWideArray = { "a", "b" };
enum Foo2 {
BAR1,
BAR2
;
public String getS() { return sysWideArray[this.ordinal()]; }
}
static void printFoo2() {
for(Foo2 f : Foo2.values()) {
System.out.println("E: " + f + " getS()=" + f.getS());
}
}
并在你的主要():
System.out.println("==================");
printFoo2();
System.out.println("==================");
sysWideArray = new String[] { "one", "two" };
printFoo2();
...所以你已经将枚举与其可变部分分开了
答案 3 :(得分: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.
(我个人会使用Guava ImmutableMap,但你可能不想使用Guava)。
然后,您可以将Map<Foo, String>
传递到需要执行映射的位置:
void doSomething(Foo value, Map<Foo, String> mapping) {
System.out.println(mapping.get(value));
}
如果您认为更整洁,可以定义界面而不是使用地图:
interface FooStrategy {
String get(Foo value);
}
但想法是一样的:将FooStrategy
传递到您需要将Foo
转换为String
的地方。
void doSomething(Foo value, FooStrategy mapping) {
System.out.println(mapping.get(value));
}
答案 4 :(得分:0)
好吧,如果我说得对,你就有Enum with Strings ...... 所以尝试Enum with constructor ..
public enum Foo {
BAR1("ONE"),
BAR2("TWO")
;
private final String text;
/**
* @param text
*/
private Strings(final String text) {
this.text = text;
}
/* (non-Javadoc)
* @see java.lang.Enum#toString()
*/
@Override
public String toString() {
return text;
}
}
请记住,枚举器必须具有不同的名称,因此BAR1(&#34; 1&#34;)和BAR1(&#34; x&#34;)不能以相同的数据类型共存...
答案 5 :(得分:0)
你可以让Enum构造函数有2个参数,比如BAR1(&#34; 1&#34;,&#34; x&#34;),然后在Enum中创建一个静态方法,它将返回一个值或另一个取决于参数。
答案 6 :(得分:0)
除this解决方案外,您还可以创建界面
interface FooConverter{
String convert(Foo foo);
}
然后,您可以根据需要提供尽可能多的实现,并且您的枚举可能包含您需要的任意数量的值。您也可以使它更通用,然后您不能仅限于String
和Foo