用数字键枚举

时间:2019-07-20 05:36:32

标签: java enums

在我的前端html中,当未选择任何国家时,将保存国家0。

在后端,在我的Java代码中,我希望选择的任何国家(地区)为0到。

我在0 ("");上遇到语法错误

因此,当我获得国家代码0时,枚举代码将不会在System.out.println(Country.valueOf("0").getCountry());上失败

多谢,谢谢。

public static void main (String []args) {
    System.out.println(Country.valueOf("SG").getCountry());
}

public static enum Country {
    MY ("Malaysia"),   
    SG ("Singapore"),   
    ID ("Indonesia"),
    0 (""); //for null blank

    private final String country;

    private Country(String levelCode) {
        this.country = levelCode;
    }   

    public String getCountry() {
        return this.country;
    }
}

5 个答案:

答案 0 :(得分:1)

您可以创建自己的valueOf方法,并在代码中使用它,因为Enum.valueOf是静态的,我们无法直接覆盖它,因此我们需要为该方法使用另一个名称

public static Country getValue(String code) {
    if (code == null || code.isEmpty() || code.equals("0")) {
        return NO_COUNTRY;
    }
    return valueOf(code);
} 

我向这样定义的枚举中添加了一个NO_COUNTRY

NO_COUNTRY("")

示例

public static void main(String[] args) throws Exception {
  System.out.printf("[%s]\n", Country.getValue("SG").getCountry());
  System.out.printf("[%s]\n", Country.getValue("0").getCountry());
}

收益

  

[新加坡]
  []

答案 1 :(得分:1)

虽然其他答案都包含有用的建议,但我想解释一下您出错的原因以及Java枚举的局限性。

出现语法错误的原因是,在Java(和大多数其他编程语言)中,枚举常量是标识符,并且标识符必须以字母开头(或下划线,当然不建议使用下划线)。 0不是字母。

这反过来也意味着Country.valueOf("0")不管您做什么都不起作用(可能有人想像过在枚举中覆盖该方法,但这是不可能的)。

两个建议:

  1. 使用另一个名称,以字母开头。

       NULL_BLANK (""); //for null blank
    
  2. 使用null代表任何国家。

对于其他名称,我在考虑COUNTRY_0BLANKZERO。例如,无论您使用上面的第1项还是第2项,都必须编写自己的查找方法,例如Joakim Danielson’s answer

编辑:一个可能更好的解决方案是一个枚举,其中构造函数将键名和国家/地区名称都作为参数:

public static enum Country {
    MALAYSIA ("MY", "Malaysia"),   
    SINGAPORE ("SG", "Singapore"),   
    INDONESIA ("ID", "Indonesia"),
    NULL_BLANK ("0", ""); //for null blank

    private static final Map<String, Country> BY_KEY
            = Arrays.stream(values()).collect(Collectors.toMap(c -> c.key, c -> c));

    public static Country of(String key) {
        return BY_KEY.get(key);
    }

    private final String key;
    private final String country;

    private Country(String key, String name) {
        this.key = key;
        this.country = name;
    }   

    public String getCountry() {
        return this.country;
    }
}

一个优点是它允许使用更好的枚举常量名称,而不是MALAYSIA,例如MY。我已经提供了of方法进行查找。像这样使用:

        System.out.println("MY -> \"" + Country.of("MY").getCountry() + "\"");
        System.out.println("0  -> \"" + Country.of("0").getCountry() + "\"");

输出:

MY -> "Malaysia"
0  -> ""

答案 2 :(得分:0)

根据您的要求,您可以像这样写而不必写0 (""); //for null blank

ZERO ("NO-COUNTRY");

NO_COUNTRY("ZERO");

答案 3 :(得分:0)

为什么不使用HasMap (推荐)

public final static Map countries = new HashMap<String, String>();
static {
    countries.put("MY", "Malaysia");
    countries.put("SG", "Singapore");
    countries.put("ID", "Indonesia");
    countries.put("0", "");
}

答案 4 :(得分:0)

当传递的字符串未映射到给定枚举的任何枚举值时,

Enum.valueOf引发异常。此外,valueOfO(n)-它必须迭代枚举的所有元素才能找到匹配的枚举。 尝试改用内部Map<String,Country>

import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

class ScratchStackOverflowQuestion57122100 {
    public static enum Country {
        MY ("Malaysia"),
        SG ("Singapore"),
        ID ("Indonesia"),
        FALLBACK(null);

        private static final Map<String, Country> stringMapping =
                Arrays.stream(Country.values())
                .collect(Collectors.toMap(Country::getCountry, Function.identity()));

        private final String country;

        Country(String levelCode) {
            this.country = levelCode;
        }

        public String getCountry() {
            return this.country;
        }

        //caller has to handle non-presence
        public static Optional<Country> tryFromString(String input) {
            return Optional.ofNullable(stringMapping.get(input));
        }

        //handle the error internal
        public static Country fromString(String input) {
            return tryFromString(input).orElse(FALLBACK);
        }
    }
}

这有以下好处:如果仅添加tryFromString,则可以让调用方处理错误,则不必指定后备选项-这样可以解决0的问题。现在,查找确实非常快,并且将来也不会引发异常,因为未映射的值总是映射到FALLBACK中的fromString