我有两个相关的枚举。
Enum1:
public enum HttpMethodName
{
GET, POST, PUT, DELETE;
}
Enum2:
public enum ProtocolOperation {
CREATE(1), RETRIEVE(2), UPDATE(3), DELETE(4), NOTIFY(5);
private BigInteger operationId;
public BigInteger getOperationId() {
return operationId;
}
private ProtocolOperation(int operationId) {
this.operationId = BigInteger.valueOf(operationId);
}
}
枚举值的映射为:
Create--> POST
Retrieve--> GET
Update--> PUT
Delete--> DELETE
Notify---> POST
因此除了POST
个案例之外,值之间存在一对一的映射,根据条件可以有Create
或Notify
两个值。
我在考虑将映射保持为List
:
public enum HttpMethodName
{
POST(new List(ProtocolOperation.CREATE, ProtocolOperation.NOTIFY)) ,GET ( new List(ProtocolOperation.RETRIEVE) ) ,
PUT (new List(ProtocolOperation.UPDATE) ,DELETE(new List(ProtocolOperation.DELETE) ;
List<ProtocolOperation > ops;
HttpMethodName (List<ProtocolOperation> ops)
{
this.ops = ops;
}
}
有更好的方法吗?
修改
我希望从HttpMethodName <----> ProtocolOperation
答案 0 :(得分:8)
为什么你觉得你目前的方法不能令人满意?
如果不了解您的疑虑,我只能建议删除样板:
import static ProtocolOperation.*;
public enum HttpMethodName {
GET(RETRIEVE),
POST(CREATE, NOTIFY),
PUT(UPDATE),
DELETE(ProtocolOperation.DELETE);
final List<ProtocolOperation> ops;
HttpMethodName(ProtocolOperation... ops) {
this.ops = Collections.unmodifiableList(Arrays.asList(ops));
}
}
如果您希望以两种方式进行映射,则首先将映射从ProtocolOperation
硬编码到HttpMethodName
(因为它不需要列表)并在{{{{}}中创建一个简单的搜索方法1}}:
MttpMethodName
由于您拥有恒定且数量较少的值,因此无需在public enum ProtocolOperation {
CREATE(1, HttpMethodName.POST),
RETRIEVE(2, HttpMethodName.GET),
UPDATE(3, HttpMethodName.PUT),
DELETE(4, HttpMethodName.DELETE),
NOTIFY(5, HttpMethodName.POST);
private BigInteger operationId;
private HttpMethodName methodName;
public BigInteger getOperationId() {
return operationId;
}
public HttpMethodName getMethodName() {
return methodName;
}
private ProtocolOperation(int operationId, HttpMethodName httpMethodName) {
this.methodName = httpMethodName;
this.operationId = BigInteger.valueOf(operationId);
}
}
public enum HttpMethodName {
GET,
POST,
PUT,
DELETE;
List<ProtocolOperation> getProtocolOperations() {
List<ProtocolOperation> ops = new ArrayList<ProtocolOperation>(2);
for (ProtocolOperation op : ProtocolOperation.values()) {
if (op.getMethodName() == this) {
ops.add(op);
}
}
return ops;
}
}
中创建最终静态地图以提供向后映射,线性搜索对于您的情况来说足够快。
答案 1 :(得分:4)
使用箭头显示从ProtocolOperation
到HttpMethodName
的映射,因此它们是简单的引用,而不是列表。
反向映射可以是一个静态方法,它迭代匹配的5个枚举值。只有5个值,所以顺序搜索足够快,除非你是在一个非常紧凑的循环中做的事情,在这种情况下这是不可能的。此外,在分析器说您遇到问题之前,不应该对性能进行编码。
您按照以下步骤操作:
// From ProtocolOperation to HttpMethodName
HttpMethodName method = ProtocolOperation.CREATE.getHttpMethodName();
// From HttpMethodName to ProtocolOperation
ProtocolOperation op = ProtocolOperation.forMethod(HttpMethodName.GET);
实现:
public enum HttpMethodName
{
GET, POST, PUT, DELETE;
}
public enum ProtocolOperation {
CREATE (1, HttpMethodName.POST),
RETRIEVE(2, HttpMethodName.GET),
UPDATE (3, HttpMethodName.PUT),
DELETE (4, HttpMethodName.DELETE),
NOTIFY (5, HttpMethodName.POST);
private final int operationId;
private final HttpMethodName httpMethodName;
private ProtocolOperation(int operationId, HttpMethodName httpMethodName) {
this.operationId = operationId;
this.httpMethodName = httpMethodName;
}
public int getOperationId() {
return this.operationId;
}
public HttpMethodName getHttpMethodName() {
return this.httpMethodName;
}
public static List<ProtocolOperation> forMethod(HttpMethodName httpMethodName) {
List<ProtocolOperation> ops = new ArrayList<>();
for (ProtocolOperation op : values())
if (op.httpMethodName == httpMethodName)
ops.add(op);
return ops;
}
}
答案 2 :(得分:1)
我会将逻辑与枚举分开。你的方法是紧密耦合,弹性较小。使用这种带变换metod的库你会更灵活
private static final Map<HttpMethodName , ProtocolOperation> mapping = new HashMap<>();
static {
mapping .put(Create, POST);
// rest of methods
}
这里是你的映射方法的主体(我正在使用Jdk8):
public static Optional<HttpMethodName > map(ProtocolOperation op){
if (!mapping.containsKey(op)){
return Optional.empty();
}
return Optional.of(mapping.get(op));
}
简而言之:枚举不应该有任何与之关联的业务逻辑,对于映射和转换,应该使用外部方法(utils)。
<强>更新强>: 正如@Andreas正确指出的那样,在这个特殊的例子中,映射是固定的,不应该扩展,你可以继续他的初始化方式:
HttpMethodName(ProtocolOperation... ops) {
this.ops = Collections.unmodifiableList(Arrays.asList(ops));
}