Kamini
Kamini

Reputation: 690

How to avoid if statements which returns value based on the input in java 8

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.

Upvotes: 1

Views: 199

Answers (6)

Kamini
Kamini

Reputation: 690

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

}

Upvotes: 0

Eklavya
Eklavya

Reputation: 18480

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

Upvotes: 1

Amar Dev
Amar Dev

Reputation: 1479

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.

Upvotes: 0

Hadi
Hadi

Reputation: 17299

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

Upvotes: 2

Major Ben
Major Ben

Reputation: 139

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

Upvotes: 0

pafau k.
pafau k.

Reputation: 1687

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.

Upvotes: 0

Related Questions