How to simplify multiple ifs statements with lambda

104 Views Asked by At

How can I simplify this example code to be more elegant, for example in functional style if it possible.

  private static String resolveTypes(String messageType, String accountType) {
    String result = "";
    if(messageType.equals("PDF") && accountType.equals("NEXT")){
      result = "2015";
    }
    if(messageType.equals("CSV") && accountType.equals("NEXT")){
      result = "2016";
    }
    if(messageType.equals("CSV") && accountType.equals("BEFORE")){
      result = "2017";
    }
    if(messageType.equals("PDF") && accountType.equals("BEFORE")){
      result = "2018";
    }
    return result;
  }
3

There are 3 best solutions below

5
On BEST ANSWER

How would lambdas help at all?

@Value
public static class MessageAccountKey {
   // this class needs a better name;
   // you'd know better what it represents
   String messageType, accountType;
}

private static final Map<MessageAccountKey, Integer> MAP = Map.of(
    new MessageAccountKey("PDF", "NEXT"), 2015,
    new MessageAccountKey("CSV", "NEXT"), 2016,
    new MessageAccountKey("CSV", "BEFORE"), 2017,
    new MessageAccountKey("PDF", "BEFORE"), 2018);

private static int resolveType(String messageType, String accountType) {
 // consider changing to a single arg of type Key.
  return MAP.getOrDefault(new MessageAccountKey(messageType, accountType), 0);
}

The 'key' class needs functional equals and hashCode impls, here done with lombok's @Value.

The MAP can also be built up from an input text file (use getResourceAsStream and a static initializer if you prefer.

2
On

You could combine the strings, with a separator, then use a switch statement:

private static String resolveTypes(String messageType, String accountType) {
    switch (messageType + ':' + accountType) {
        case "PDF:NEXT": return "2015";
        case "CSV:NEXT": return "2016";
        case "CSV:BEFORE": return "2017";
        case "PDF:BEFORE": return "2018";
        default: return "";
    }
}
0
On

If you have a limited number of values a map could also be an alternative:

private static String resolveTypes(String messageType, String accountType) {
    Map<String,Map<String,String>> map = Map.of( 
            "PDF",Map.of("NEXT", "2015", "BEFORE","2016"),
            "CSV",Map.of("NEXT", "2017", "BEFORE","2018"));
    return map.getOrDefault(messageType, new HashMap<>()).getOrDefault(accountType, "");
}