如何避免if语句基于java 8中的输入返回值

问题描述 投票:1回答:5

我输入的是RoleID(Long数据类型),所以我不能使用切换大小写,我现在正在使用if else语句。我已经在寻找解决方案,但没有找到理想的解决方案。

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
}

我想知道是否还有其他方法可以实现相同的目的,因为输入为Long,所以我不想使用switch,因为它将需要很多转换。

java java-8
5个回答
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());
  }
}

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映射中。


0
投票

所以要注意几件事。如果您重写了枚举的equals方法,它将看起来像什么。是否简单检查一下roleId是否等于枚举id:

public boolean equals(long roleId) {
   return (int) roleId == id
}

但是我认为解决此问题的最佳方法是使用地图:

HashMap<int, RoleEnum> validation = new HashMap<int, RoleEnum>();

RoleEnum fetchProcessForRole(long roleId){
   return validation.get((int) roleId);
}

0
投票

我不确定RoleEnum是否在您的控制之下。

但是我不明白代表什么

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

我认为它代表选项3,在您的用例中可能是必需的。但是它有不止一个改变的理由。请考虑将它们隔离。

如果这样做,您的函数将更改为接受RoleEnum并返回RoleValidationEnum

您可以使用switch来确定哪个RoleEnum返回哪个RoleValidationEnum

我希望这会有所帮助。


0
投票

您可以使用roleId枚举

RoleEnum role =
        EnumSet.allOf(RoleEnum.class).stream().filter(r -> r.getId() == roleId).findFirst().orElseThrow();

然后使用开关盒来获取结果,无需转换。

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;
 }
© www.soinside.com 2019 - 2024. All rights reserved.