Java 两个相关的枚举映射?
我有两个相关的枚举 列举1: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
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;
}
}