英文:
How to avoid if statements which returns value based on the input in java 8
问题
我有一个Long数据类型的roleID作为输入,所以我不能使用switch case,
我目前正在使用if else语句。
我已经寻找了解决方案,但没有找到完美的解决方案。
RoleEnum fetchProcessForRole(roleID) {
if (RoleEnum.USER.getId() == roleID) {
return RoleEnum.USER_VALIDATION; // 这是int类型
} else if (RoleEnum.ADMIN.getId() == roleID) {
return RoleEnum.ADMIN_VALIDATION;
} else if (RoleEnum.MGR.getId() == roleID) {
return RoleEnum.MGR_VALIDATION;
}
}
RoleEnum {
USER(1,"USER","userrpt"),
ADMIN(2,"ADMIN","adminrpt"),
MGR(3,"MGR","mgrrpt"),
USER_VALIDATION(4,"USER_VALIDATION","userrpt"),
ADMIN_VALIDATION(5,"ADMIN_VALIDATION","adminrpt"),
MGR_VALIDATION(6,"MGR_VALIDATION","mgrrpt");
// 它有int id,String名称和它的getter方法
}
我想知道是否有其他方法来实现相同的事情,因为输入是Long,我不想使用switch,因为它会需要很多转换。
英文:
I have input as roleID (of Long data type), so I can not use switch case,
I am using if else statements right now.
I have search for the solution but have not came across with the perfect one.
RoleEnum fetchProcessForRole(roleID) {
if (RoleEnum.USER.equals(roleID) {
return RoleEnum.USER_VALIDATION; // this is of int type
} else if (RoleEnum.ADMIN.equals(roleID) {
return RoleEnum.ADMIN_VALIDATION;
} else if (RoleEnum.MGR.equals(roleID) {
return RoleEnum.MGR_VALIDATION;
}
}
RoleEnum {
USER(1,"USER","userrpt"),
ADMIN(2,"ADMIN","adminrpt"),
MGR(3,"MGR","mgrrpt"),
USER_VALIDATION(4,"USER_VALIDATION","userrpt"),
ADMIN_VALIDATION(5,"ADMIN_VALIDATION","adminrpt"),
MGR_VALIDATION(6,"MGR_VALIDATION","mgrrpt");
// it have int id, String name and its getters
}
I want to know if there is any other way to achieve same thing, as the input is Long, I do not want to use switch as it will require lot of conversions.
答案1
得分: 2
你可以创建一个静态类来存储枚举常量在地图中。因为枚举常量的第三个参数是相同的(USER
和USER_VALIDATION
等等),所以你可以根据这个参数初始化地图。这样地图就会初始化为map<String, RoleEnum>
,其中键是第三个参数,值是枚举常量。
考虑到我假设USER_VALIDATION
在USER
之后,其他情况也是一样的。在根据ID找到roleEnum
之后,你可以基于roleEnum
的第三个参数从地图中获取它的一对。
enum RoleEnum {
USER(1, "USER", "userrpt"),
ADMIN(2, "ADMIN", "adminrpt"),
MGR(3, "MGR", "mgrrpt"),
USER_VALIDATION(4, "USER_VALIDATION", "userrpt"),
ADMIN_VALIDATION(5, "ADMIN_VALIDATION", "adminrpt"),
MGR_VALIDATION(6, "MGR_VALIDATION", "mgrrpt");
static class Holder {
private static HashMap<String, RoleEnum> map = new HashMap<>();
public HashMap<String, RoleEnum> getMap() {
return map;
}
}
private long id;
private String name;
private String des;
RoleEnum(long id, String name, String des) {
this.id = id;
this.name = name;
this.des = des;
Holder.map.put(this.getDes(), this);
}
public static Map<String, RoleEnum> getMap() {
return Holder.map;
}
public static RoleEnum findById(Long id) {
RoleEnum roleEnum = EnumSet.allOf(RoleEnum.class)
.stream().filter(role -> role.getId() == id)
.findFirst().orElse(null);
return getMap().get(roleEnum.getDes());
}
}
英文:
You can create a static class that stores enum constants on the map. because the third argument for pair of enum constants is the same(USER
& USER_VALIDATION
and ...) you can init the map base on this param. so the map will initial map<String, RoleEnum>
which the key is third param and value is enum constant.
consider this fact that I supposed USER_VALIDATION
comes after USER
and for others too. after finding the roleEnum
based on id then you can get pair of it from the map based on roleEnum
's third param.
enum RoleEnum {
USER(1, "USER", "userrpt"),
ADMIN(2, "ADMIN", "adminrpt"),
MGR(3, "MGR", "mgrrpt"),
USER_VALIDATION(4, "USER_VALIDATION", "userrpt"),
ADMIN_VALIDATION(5, "ADMIN_VALIDATION", "adminrpt"),
MGR_VALIDATION(6, "MGR_VALIDATION", "mgrrpt");
static class Holder {
private static HashMap<String, RoleEnum> map = new HashMap<>();
public HashMap<String, RoleEnum> getMap() {
return map;
}
}
private long id;
private String name;
private String des;
RoleEnum(long id, String name, String des) {
this.id = id;
this.name = name;
this.des = des;
Holder.map.put(this.getDes(), this);
}
public static Map<String, RoleEnum> getMap() {
return Holder.map;
}
public static RoleEnum findById(Long id) {
RoleEnum roleEnum = EnumSet.allOf(RoleEnum.class)
.stream().filter(role -> role.getId() == id)
.findFirst().orElse(null);
return getMap().get(roleEnum.getDes());
}
}
答案2
得分: 1
你可以使用 roleId
来获取枚举。
RoleEnum role =
EnumSet.allOf(RoleEnum.class).stream().filter(r -> r.getId() == roleId).findFirst().orElseThrow();
然后使用 switch-case 获取结果,无需转换。
RoleEnum result;
switch (role) {
case USER :
result = RoleEnum.USER_VALIDATION;
break;
case ADMIN :
result = RoleEnum.ADMIN_VALIDATION;
break;
case MGR :
result = RoleEnum.MGR_VALIDATION;
break;
default:
result = null;
}
英文:
You can get enum using roleId
RoleEnum role =
EnumSet.allOf(RoleEnum.class).stream().filter(r -> r.getId() == roleId).findFirst().orElseThrow();
Then use switch-case to get result no conversion needed.
RoleEnum result;
switch (role) {
case USER :
result = RoleEnum.USER_VALIDATION;
break;
case ADMIN :
result = RoleEnum.ADMIN_VALIDATION;
break;
case MGR :
result = RoleEnum.MGR_VALIDATION;
break;
default:
result = null;
}
答案3
得分: 0
如果您不能触摸RoleEnum
,并且您有测试来证明枚举的顺序永远不会改变,以及另一组测试来证明id按从1递增的顺序排列,那么您可能可以执行这样的可怕操作:
RoleEnum fetchProcessForRole(long roleID) {
RoleEnum[] values = RoleEnum.values();
if (roleID < 1 || roleID > values.length) {
throw new IllegalArgumentException("Role id not found");
}
return values[(int) roleID - 1];
}
但是,您真的应该将所有内容存储在一个id:enum映射中。
英文:
If you're not allowed to touch RoleEnum
, and you have tests to prove the order of enums never changes, and another set of tests to prove the id's are in increasing order from 1, then you could possibly do such an abomination:
RoleEnum fetchProcessForRole(long roleID) {
RoleEnum[] values = RoleEnum.values();
if (roleID < 1 || roleID > values.length) {
throw new IllegalArgumentException("Role id not found");
}
return values[(int) roleID - 1];
}
But you really should just store it all in an id:enum map.
答案4
得分: 0
以下是翻译好的内容:
所以有几点需要注意。如果您已经重写了枚举的 equals 方法,那么它是什么样子?它是否只是简单地检查 roleId 是否等于枚举的 id:
public boolean equals(long roleId) {
return (int) roleId == id;
}
但我认为处理这个问题的最佳方法是使用一个 Map:
HashMap<Integer, RoleEnum> validation = new HashMap<Integer, RoleEnum>();
RoleEnum fetchProcessForRole(long roleId){
return validation.get((int) roleId);
}
英文:
So couple things to note. What does the equals method for enum look like if you have overridden it. Is it a simple check to see if the roleId is equal to the enums id:
public boolean equals(long roleId) {
return (int) roleId == id
}
But I think the best way to approach this is to use a Map:
HashMap<int, RoleEnum> validation = new HashMap<int, RoleEnum>();
RoleEnum fetchProcessForRole(long roleId){
return validation.get((int) roleId);
}
答案5
得分: 0
我不确定 RoleEnum
是否在您的控制范围内。
但我不理解它代表着什么。
- 用户角色
- 用户角色所需的验证
- 两者皆是
我认为它代表选项 3,可能在您的用例中是必需的。但它有不止一个变更的原因。请考虑对它们进行分离。
如果您这样做,您的函数将更改为接受一个 RoleEnum
并返回一个 RoleValidationEnum
。
您可以使用 switch
来决定哪个 RoleEnum
返回哪个 RoleValidationEnum
。
希望这对您有所帮助。
英文:
I am not sure if the RoleEnum
is under your control or not.
But I don't understand what is represents
- User's role
- Validation required for a user's role
- Both
I think it represents option 3, perhaps required in your use case. But it has more than one reason to change. Please consider segregating them.
If you do so, your function changes to accept a RoleEnum
and return a RoleValidationEnum
.
You can use a switch
to decide which RoleEnum
returns which RoleValidationEnum
.
I hope this helps.
答案6
得分: 0
你好,我在这里找到了以下解决方案。
RoleEnum fetchProcessForRole(Long roleID) {
String name = RoleEnum.values()[(int) roleID].getName().toUpperCase();
return EnumSet.allOf(RoleEnum.class).stream()
.filter(role -> role.getName().startsWith(name + "_"))
.findFirst()
.get();
}
英文:
Hi I got below solution on this.
RoleEnum fetchProcessForRole(Long roleID) {
String name= RoleEnum.values()[int(long)roleID].getName().toUpperCase();
return EnumSet.allOf(RoleEnum.class).stream()
.filter(role -> role.getName().startsWith(name+"_"))
.findFirst()
.get();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论