Java 两个相关的枚举映射?

Java 两个相关的枚举映射?,java,enums,Java,Enums,我有两个相关的枚举 列举1: public enum HttpMethodName { GET, POST, PUT, DELETE; } 列举2: public enum ProtocolOperation { CREATE(1), RETRIEVE(2), UPDATE(3), DELETE(4), NOTIFY(5); private BigInteger operationId; public BigInteger getOperationId

我有两个相关的枚举

列举1:

public enum HttpMethodName 
{
    GET, POST, PUT, DELETE; 
}
列举2:

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

我正在考虑将映射保留为
列表

    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
{
POST(新列表(ProtocolOperation.CREATE,ProtocolOperation.NOTIFY)),GET(新列表(ProtocolOperation.RETRIEVE)),
放置(新列表(ProtocolOperation.UPDATE),删除(新列表(ProtocolOperation.DELETE);
名单行动;
HttpMethodName(列表操作)
{
this.ops=ops;
}
}
有更好的方法吗

编辑:


我希望从
HttpMethodName ProtocolOperation
中映射两种方法。我希望将逻辑与enum分离。您的方法是紧密耦合的,弹性较小。有了这种带有转换方法的库,您将更加灵活

private static final Map<HttpMethodName , ProtocolOperation> mapping = new HashMap<>();
static {
mapping .put(Create, POST);
// rest of methods
}

为什么你觉得你目前的方法不令人满意

在不了解您的顾虑的情况下,我只能建议删除样板文件:

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));
    }
}

由于您具有常量和少量值,因此不需要在
HttpMethodName
中创建最终的静态映射来提供向后映射,线性搜索对于您的情况来说已经足够快了。

创建从
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;
    }
}
公共枚举HttpMethodName
{
获取、发布、放置、删除;
}
公共枚举协议操作{
创建(1,HttpMethodName.POST),
检索(2,HttpMethodName.GET),
更新(3,HttpMethodName.PUT),
删除(4,HttpMethodName.DELETE),
通知(5,HttpMethodName.POST);
私有最终int操作ID;
私有最终HttpMethodName HttpMethodName;
专用协议操作(int-operationId,HttpMethodName-HttpMethodName){
this.operationId=operationId;
this.httpMethodName=httpMethodName;
}
public int getOperationId(){
返回此操作ID;
}
公共HttpMethodName getHttpMethodName(){
返回此.httpMethodName;
}
方法的公共静态列表(HttpMethodName HttpMethodName){
List ops=new ArrayList();
for(ProtocolOperation op:values())
如果(op.httpMethodName==httpMethodName)
增列(op);
返回操作;
}
}

为什么你认为枚举不应该包含映射?对我来说,HTTP方法和它们的角色之间的关系是由HTTP协议确定的。如果有几个(比如说,两个以上)的话,你是对的不同的映射涉及
HttpMethodName
enum,但我发现这不太可能。几年后,我采用了相同的方法。在本例中,这可能有意义,但通常我们倾向于为扩展打开代码。在实用程序类中拥有映射将使我们能够为其他客户机/模块等创建单独的映射。但我认为st承认在这个例子中,将枚举列表保存在枚举的内部是很好的。因为OP想要一个从
ProtocolOperation
HttpMethodName
的映射,所以你应该用另一种方法来做,这也会消除对列表的需要。@Andreas:这会导致每次迭代枚举值来找到映射???@reas,是什么让你认为OP想要从
ProtocolOperation
映射到
HttpMethodName
?从他的话
判断,枚举值的映射为:
,下表我假设他想要从
HttpMethodName
映射到
ProtocolOperation
。我想要从两边映射。我正在编辑question@SiddharthTrikha我更新了我的答案,以覆盖两种方式的映射。这是最后一次编辑“两者”这个词吗粗体,对我的答案的反应?因为我的答案在两个方向上都有映射。使用可以在Guava中使用BiMap。你希望有两个
Map
实例,还是现有的答案推荐方法足够好?也许你也可以分享如何在你的代码库中进一步使用这种关系?哇,我发布了与你。这不是故意的。投票给你:)
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;
    }
}
// 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;
    }
}