He escrito un analizador para un formato típico (propietario) de texto en un archivo de texto. Una de las tareas principales del analizador es convertir el nombre de la función en la llamada, siendo secundaria la mutación de los parámetros y/o su posición en la llamada.
Ejemplo:
Func1(bla1,bla2,bla3)se convierte
Func2(bla1) // again, licensing issues, so cannot show the actual file Hay un mínimo de 50 funciones separadas de este tipo. El programa está funcionando bien. El único problema es que si se agregan algunas funciones nuevas en el futuro, tendré que modificar 2 cosas, una ArrayList que contiene el nombre de todas las funciones cuyas llamadas deben modificarse y una declaración de cambio que realmente modifica las llamadas. Puede suceder que un nombre de función en particular esté presente como un caso en la declaración de cambio, pero siendo yo el monstruo olvidadizo que soy, el nombre de la función no está presente en ArrayList.
Lo que estaba pensando era que si pudiera pedirle a Java que generara ese ArrayList por mí (es solo una Lista de cadenas, con cada entrada como una etiqueta de caso), podría ayudar. ¿Hay alguna forma en Java 8 para hacer esto?
Ejemplo:
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>;De la especificación del lenguaje Java : 14.11. The switch Statement Haga clic en el enlace para la 14.11. The switch Statement , puede ver que los casos del interruptor pueden ser una expresión constante o un nombre constante de enumeración y siguiendo la definición de la expresión constante aquí, haga clic en el enlace .
Por lo tanto, los valores en cada declaración de caso deben ser valores constantes de tiempo de compilación del mismo tipo de datos que el valor del interruptor ( literales , constantes de enumeración o variables constantes finales : marcadas con el modificador final e inicializadas).
Está buscando la respuesta a la pregunta: ¿Se puede saber el número de casos en tiempo de ejecución ? No, no puede porque los casos deben ser constantes de tiempo de compilación.
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; } } }No es posible enumerar las etiquetas de los case desde un switch .
Sin embargo, puede mantener un Map que asigna nombres de funciones a sus correspondientes acciones a realizar:
Map<String, Runnable> functions = Map.of( "func1", () -> doSomething(), "func2", () -> doSomethingElse(), ... ); Para obtener los nombres de las funciones, puede usar keySet() para obtener todos los nombres de las funciones (o use containsKey para verificar si existe un nombre de función). Y en lugar de la declaración de cambio, simplemente podría usar
functions.get(functionName).run(); Tenga en cuenta que utilicé un Runnable como valor de mapa, lo que permite realizar algún código, sin entrada. Esto se debe a que no ha mostrado qué acciones están realizando realmente sus casos de cambio, o cómo se ve realmente "mutar los parámetros y/o su posición en la llamada" . Es posible que desee reemplazar Runnable con algo más apropiado.
No puede derivar dinámicamente la colección de declaraciones de casos del conmutador. Sin embargo, puede crear una enumeración de las funciones y usarla en el interruptor y para ensamblar su Lista. Por ejemplo...
public enum Function { FUNC1("func1"), FUNC2("func2"), ... ; private String functionName; private Function(String functionName) { ... } public String functionName() { ... } public static Function byFunctionName(String functionName) { ... } }Encuentre la instancia de la función que coincida con la cadena que está activando actualmente y active la función.
Function function = Function.byFunctionName(functionName); switch (function) { case FUNCT1: ... case FUNCT2: ... ... etc ... }Y la Lista de nombres de funciones se puede crear a partir de la misma enumeración.
List<String> functionNames = Arrays.stream(Function.values()) .map(e -> e.functionName()) .collect(Collectors.toList());