所以我有一个带有多个枚举的Java类
public class Enumerations {
public enum Days {
Monday("MON")
Tuesday("Tue")
string value;
private Days(String value){
this.value = value
}
public string getValue(){
return this.value;
}
}
public enum Months{
January("JAN")
APRIL("APR")
string value;
private Months(String value){
this.value = value
}
public string getValue(){
return this.value;
}
}
}
现在我有另一个类,我想通过字符串访问枚举类,因为我无法直接实例化枚举,因为我不知道要使用的枚举,而是从可变字符串访问枚举值(不知道也是如此)。
class EnumParser{
public static void main(String args[]){
String enum = "Days"; //Will get this value from external source so its variable(Can be months or days)
String value = "Monday" //This is going to variable as well with value unknown.
}
}
那么我如何在这里使用字符串变量将输出作为“ MON”
Enumerations.{{Days}}.{{Monday}}.getValue();
编辑了该问题以得到更清晰的视图,“ Days”和“ Mondays”都是变量。
答案 0 :(得分:1)
您可以使用if-else
或switch
语句来确定要使用的枚举,然后使用valueOf()
:
String e = "Days";
String value = "Monday";
if (e.equalsIgnoreCase(Enumerations.Days.class.getSimpleName())) {
System.out.println(Enumerations.Days.valueOf(value).getValue());
} else if (e.equalsIgnoreCase(Enumerations.Months.class.getSimpleName())) {
System.out.println(Enumerations.Months.valueOf(value).getValue());
} else {
System.out.println("Could not find enum");
}
输出:
MON
更新是基于您可能有200多个枚举的注释:
您可以像这样使用反射:
String e = "Days";
String value = "Monday";
String res = Arrays.stream(Enumerations.class.getDeclaredClasses())
.filter(c -> c.getSimpleName().equalsIgnoreCase(e))
.findFirst()
.map(c -> {
String result = null;
try {
Object o = c.getMethod("valueOf", String.class).invoke(null, value);
result = (String) o.getClass().getMethod("getValue").invoke(o);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e1) {
e1.printStackTrace();
}
return result;
}).orElse("Could not find");
System.out.println(res); //prints MON
答案 1 :(得分:0)
使用静态方法为您检索适当的枚举值:
//inside Days, skips some excess array creation
private static final Days[] VALUES = Days.values();
public static Days getDay(String day) {
return Arrays.stream(VALUES)
.filter(d -> d.value.equalsIgnoreCase(day))
.findAny(); //Optional<Days>
//can use #orElse/#orElseThrow to decide behavior for a mismatch
}
然后只需直接获取枚举即可:
Days monday = Days.getDay("MON");
您可以根据需要创建多种方法来过滤这些输入。更进一步,如果您真的想发疯,可以通过Predicate<Days>
(或任何枚举)并以这种方式进行过滤:
public static Days getDay(Predicate<Days> filter) {
return Arrays.stream(VALUES)
.filter(filter)
//In this case I'm returning null for no match
.findAny().orElse(null);
}
然后:
Days monday = Days.getDay(d -> d.getValue().equalsIgnoreCase("MON"));
现在在严格的Monday
情况下,您可以使用Days#valueOf
,但是如果搜索的字符串没有枚举常量,这将引发错误。
Days monday = Days.valueOf("Monday"); //okay
//all of these below would throw an error
monday = Days.valueOf("monday");
monday = Days.valueOf("MONDAY");
monday = Days.valueOf("not even close to monday");
我还将遵守此处的枚举约定(所有大写字母和下划线代表空格,因此MONDAY
)。
最后,如果这不仅是一个示例问题,而且您实际上正在使用天/日历变量等,则默认jdk中已经有DayOfWeek
和Month
枚举。 / p>
答案 2 :(得分:0)
尝试反射方式;
package com.company;
import java.lang.reflect.Method;
class Enumerations {
public enum Days {
Monday("MON"),
Tuesday("Tue");
String value;
Days(String value){
this.value = value;
}
public String getValue(){
return this.value;
}
}
public enum Months{
January("JAN"),
APRIL("APR");
String value;
Months(String value){
this.value = value;
}
public String getValue(){
return this.value;
}
}
}
public class Main {
public static void main(String[] args) throws Exception {
// know the specific class name
System.out.println(Enumerations.Months.class);
String enumName = "Days";
String value = "Monday";
// get the class by class name
Class c = Class.forName("com.company.Enumerations$" + enumName);
// new the object by value
Object o = Enum.valueOf(c, value);
// get the method by name
Method method = c.getMethod("getValue");
// invoke the method
System.out.println(method.invoke(o));
}
}