Home > Enterprise >  Is there any way to retrieve the Case Labels of a Switch Statement as a Collection in Java 8?
Is there any way to retrieve the Case Labels of a Switch Statement as a Collection in Java 8?

Time:04-01

I have written a parser for a typical format (proprietary) of text in a text file. One of the primary tasks of the parser is to convert function name in the call, secondary being to mutate the parameters and/or their position in the call.

Example:

Func1(bla1,bla2,bla3)

becomes

Func2(bla1) // again, licensing issues, so cannot show the actual file

There's a minimum of 50 separate such functions. The program is working fine. The only problem is that if some new functions are added in the future, I will have to alter 2 things, an ArrayList which holds the name of all the functions whose calls need to be modified, and a switch statement which actually modifies the calls. It might happen so that, a particular function name is present as a case in the switch statement, but me being the forgetful freak that I am, the function name is not present in the ArrayList.
What I was thinking was that if I could instead ask Java to generate that ArrayList for me (its just a List of strings, with each entry being a case label), it might help. Is there any way in Java 8 to do this?

Example:

String functionName = "";
switch(functionName) {
case "Func1":
    break;
case "Func2":
    break;
//bla bla bla
default:
    //whatever
} 

List<String> functionNames = <some code which returns a Collection of all case names>;

CodePudding user response:

It's not possible to list the case labels from a switch.

However, you could maintain a Map which maps function names to their corresponding actions-to-be-performed:

Map<String, Runnable> functions = Map.of(
    "func1", () -> doSomething(),
    "func2", () -> doSomethingElse(),
    ...
);

To get the function names, you could just use keySet() to get all function names (or use containsKey to check whether a function name exists). And instead of the switch statement, you could just use

functions.get(functionName).run();

Note that I used a Runnable as map value, which allows to perform some code, without input. That is because you have not shown what actions your switch cases are actually doing, or what "mutate the parameters and/or their position in the call" actually looks like. You may want to replace Runnable with something more appropriate.

CodePudding user response:

From the Java Language specification : 14.11. The switch Statement click the link , you can see that cases of the Switch can be a ConstantExpression or an EnumConstantName and following the definition of the ConstantExpression here click the link .

So the values in each case statement must be compile-time constant values of the same data type as the switch value (literals, enum constants, or final constant variables : marked with the final modifier and initialized).


You are looking for the answer of the question : can the number of cases be known At Runtime . No it cannot because the cases must be a compile time constants .

public class Swith {
    public static void main(String[] args) {
        List<String> lst = new ArrayList<>();
        switch (lst.get(0)) {
        case lst.get(0): //Compilation error : case expressions must be constant expressions
            break;
        default:
            break;
        }
    }
}

CodePudding user response:

You cannot dynamically derive the collection of case statements from the switch. However, you can create an enum of the functions and use that in the switch and to assemble your List. For example...

public enum Function {
  FUNC1("func1"), FUNC2("func2"), ... ;
  private String functionName;
  private Function(String functionName) { ... }
  public String functionName() { ... }
  public static Function byFunctionName(String functionName) { ... }
}

Find the Function instance that matches the String you are currently switching on and switch on the Function.

Function function = Function.byFunctionName(functionName);
switch (function) {
  case FUNCT1: ...
  case FUNCT2: ...
  ... etc ...
}

And the List of function names can be created from the same enum.

List<String> functionNames = Arrays.stream(Function.values())
        .map(e -> e.functionName())
        .collect(Collectors.toList());
  • Related