如何在Java 8中避免使用基于输入返回值的if语句。

huangapple go评论62阅读模式
英文:

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

你可以创建一个静态类来存储枚举常量在地图中。因为枚举常量的第三个参数是相同的(USERUSER_VALIDATION等等),所以你可以根据这个参数初始化地图。这样地图就会初始化为map<String, RoleEnum>,其中键是第三个参数,值是枚举常量。
考虑到我假设USER_VALIDATIONUSER之后,其他情况也是一样的。在根据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&lt;String, RoleEnum&gt; 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, &quot;USER&quot;, &quot;userrpt&quot;),
ADMIN(2, &quot;ADMIN&quot;, &quot;adminrpt&quot;),
MGR(3, &quot;MGR&quot;, &quot;mgrrpt&quot;),
USER_VALIDATION(4, &quot;USER_VALIDATION&quot;, &quot;userrpt&quot;),
ADMIN_VALIDATION(5, &quot;ADMIN_VALIDATION&quot;, &quot;adminrpt&quot;),
MGR_VALIDATION(6, &quot;MGR_VALIDATION&quot;, &quot;mgrrpt&quot;);
static class Holder {
private static HashMap&lt;String, RoleEnum&gt; map = new HashMap&lt;&gt;();
public HashMap&lt;String, RoleEnum&gt; 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&lt;String, RoleEnum&gt; getMap() {
return Holder.map;
}
public static RoleEnum findById(Long id) {
RoleEnum roleEnum = EnumSet.allOf(RoleEnum.class)
.stream().filter(role -&gt; 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 -&gt; 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 &lt; 1 || roleID &gt; values.length) {
throw new IllegalArgumentException(&quot;Role id not found&quot;);
}
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&lt;int, RoleEnum&gt; validation = new HashMap&lt;int, RoleEnum&gt;();
RoleEnum fetchProcessForRole(long roleId){
return validation.get((int) roleId);
}

答案5

得分: 0

我不确定 RoleEnum 是否在您的控制范围内。

但我不理解它代表着什么。

  1. 用户角色
  2. 用户角色所需的验证
  3. 两者皆是

我认为它代表选项 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

  1. User's role
  2. Validation required for a user's role
  3. 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 -&gt; role.getName().startsWith(name+&quot;_&quot;))
.findFirst()
.get();
}

huangapple
  • 本文由 发表于 2020年5月31日 03:45:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/62107839.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定