我编写了一个Java枚举,其中值具有各种属性.这些属性可以通过以下任何方式存储:
使用字段:
enum Eenum {
V1(p1),
V2(p2);
private final A attr;
public A attr() { return attr; }
private Eenum(A attr) {
this.attr = attr;
}
}
Run Code Online (Sandbox Code Playgroud)
使用抽象方法:
enum Eenum {
V1 {
public A attr() { return p1; }
},
V2 {
public A attr() { return p2; }
}
public abstract A attr();
}
Run Code Online (Sandbox Code Playgroud)
使用班级地图:
enum Eenum {
V1,
V2;
public A attr() { return attrs.get(this); }
private static final Map<A> attrs;
static {
ImmutableMap.Builder<Eenum, A> builder = ImmutableMap.builder();
builder.put(V1, p1);
builder.put(V2, p2);
attrs = builder.build();
}
}
Run Code Online (Sandbox Code Playgroud)
我该如何决定何时选择哪个?
谢谢!
(我正在回答我自己的问题,以便我可以分享我在尝试时学到的一些东西。)
为了针对您的具体案例做出决定,您应该提出以下问题:
1:属性值是否涉及前向引用?
有时V1的属性可能需要引用V2,反之亦然。这种情况并不罕见。如果您正在处理这样的问题enum,方法 1 根本行不通。编译器会(正确地)抱怨非法的前向引用。可以使用其他两种方法中的任何一种。
现在,如果属性值的计算成本很高并且是一个常量,那么您希望只计算一次。使用方法 2,您必须为每个枚举值引入局部变量,并在那里缓存结果。这很冗长,但会给您带来更好的性能。对于方法 3,结果只计算一次,因此不需要做任何额外的工作。这比方法 2 更具可读性,但性能稍差。根据您的案例所保证的具体权衡,在这些之间进行设计。
2:我需要缓存结果吗?
请参阅上一个项目符号的第二段。
如果没有前向引用,也可以使用方法1。但如果属性计算涉及的计算很复杂,那么最好使用其他两种方法之一。
3:属性是否与所有枚举值相关?
如果没有,那么从逻辑上讲,您应该Map在此处使用 a 。即方法3。
4:某些枚举值的某些属性是否有默认值?
如果是这样,您可以使用所有三种方法,它们都提供不同的权衡。
使用方法 1:您将定义一个辅助构造函数,将属性初始化为默认值。如果有多个这样的属性,这可能不是一个可行的方法。
方法 2:这实际上就像 Peter Lawrey 上面建议的“第四种”方法。enum您将有一个方法返回主体中的默认值。并且某些枚举值将重写此方法以返回不同的值。这又是相当冗长的。
方法 3:只是效率较低。其他各方面都很好。
| 归档时间: |
|
| 查看次数: |
548 次 |
| 最近记录: |