我想从字符串值(或可能是任何其他值)查找枚举。我尝试了以下代码,但它不允许在初始化程序中使用静态代码。有一个简单的方法吗?
public enum Verbosity {
BRIEF, NORMAL, FULL;
private static Map<String, Verbosity> stringMap = new HashMap<String, Verbosity>();
private Verbosity() {
stringMap.put(this.toString(), this);
}
public static Verbosity getVerbosity(String key) {
return stringMap.get(key);
}
};
答案 0 :(得分:207)
使用为每个枚举自动创建的valueOf
方法。
Verbosity.valueOf("BRIEF") == Verbosity.BRIEF
对于任意值,请以:
开头public static Verbosity findByAbbr(String abbr){
for(Verbosity v : values()){
if( v.abbr().equals(abbr)){
return v;
}
}
return null;
}
如果您的探查器告诉您,只能在以后继续使用Map实现。
我知道它正在迭代所有的值,但只有3个枚举值,它几乎不值得任何其他努力,事实上,除非你有很多值我不会打扰地图它会足够快。 / p>
答案 1 :(得分:121)
你很亲密。对于任意值,请尝试以下内容:
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
// Reverse-lookup map for getting a day from an abbreviation
private static final Map<String, Day> lookup = new HashMap<String, Day>();
static {
for (Day d : Day.values()) {
lookup.put(d.getAbbreviation(), d);
}
}
private Day(String abbreviation) {
this.abbreviation = abbreviation;
}
public String getAbbreviation() {
return abbreviation;
}
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
}
}
答案 2 :(得分:15)
public static Verbosity findByAbbr(final String abbr){
return Arrays.stream(values()).filter(value -> value.abbr().equals(abbr)).findFirst().orElse(null);
}
答案 3 :(得分:13)
@Lyle的答案相当危险,我发现如果你把枚举变成一个静态的内部类,它就不起作用了。相反,我使用了类似的东西,它将在枚举之前加载BootstrapSingleton地图。
编辑 这应该不再是现代JVM(JVM 1.6或更高版本)的问题,但我认为JRebel仍然存在问题,但我没有机会重新测试。
先加载我:
public final class BootstrapSingleton {
// Reverse-lookup map for getting a day from an abbreviation
public static final Map<String, Day> lookup = new HashMap<String, Day>();
}
现在将它加载到枚举构造函数中:
public enum Day {
MONDAY("M"), TUESDAY("T"), WEDNESDAY("W"),
THURSDAY("R"), FRIDAY("F"), SATURDAY("Sa"), SUNDAY("Su"), ;
private final String abbreviation;
private Day(String abbreviation) {
this.abbreviation = abbreviation;
BootstrapSingleton.lookup.put(abbreviation, this);
}
public String getAbbreviation() {
return abbreviation;
}
public static Day get(String abbreviation) {
return lookup.get(abbreviation);
}
}
如果你有一个内部枚举,你可以在枚举定义之上定义Map,并且(理论上)应该在之前加载。
答案 4 :(得分:6)
你不能使用valueOf()?
编辑:顺便说一句,没有什么可以阻止你在枚举中使用静态{}。
答案 5 :(得分:5)
在Java语言规范7中有一个a example!这反映了您对使用自引用初始化地图的问题。
答案 6 :(得分:3)
如果它对其他人有帮助,我更喜欢的选项(此处未列出)使用Guava's Maps functionality:
public enum Vebosity {
BRIEF("BRIEF"),
NORMAL("NORMAL"),
FULL("FULL");
private String value;
private Verbosity(final String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
private static ImmutableMap<String, Verbosity> reverseLookup =
Maps.uniqueIndex(Arrays.asList(Verbosity.values()), Verbosity::getValue);
public static Verbosity fromString(final String id) {
return reverseLookup.getOrDefault(id, NORMAL);
}
}
默认情况下,您可以使用null
,throw IllegalArgumentException
或fromString
可以返回Optional
,无论您喜欢什么行为。
答案 7 :(得分:1)
也许,看看这个。它为我工作。
这样做的目的是用'/ red_color'查找'RED'。
如果static map
很多,则声明enum
并仅将enum
加载到其中只会带来一些性能优势。
public class Mapper {
public enum Maps {
COLOR_RED("/red_color", "RED");
private final String code;
private final String description;
private static Map<String, String> mMap;
private Maps(String code, String description) {
this.code = code;
this.description = description;
}
public String getCode() {
return name();
}
public String getDescription() {
return description;
}
public String getName() {
return name();
}
public static String getColorName(String uri) {
if (mMap == null) {
initializeMapping();
}
if (mMap.containsKey(uri)) {
return mMap.get(uri);
}
return null;
}
private static void initializeMapping() {
mMap = new HashMap<String, String>();
for (Maps s : Maps.values()) {
mMap.put(s.code, s.description);
}
}
}
}
请提出您的意见。
答案 8 :(得分:0)
您可以将Enum定义为以下代码:
public enum Verbosity
{
BRIEF, NORMAL, FULL, ACTION_NOT_VALID;
private int value;
public int getValue()
{
return this.value;
}
public static final Verbosity getVerbosityByValue(int value)
{
for(Verbosity verbosity : Verbosity.values())
{
if(verbosity.getValue() == value)
return verbosity ;
}
return ACTION_NOT_VALID;
}
@Override
public String toString()
{
return ((Integer)this.getValue()).toString();
}
};
答案 9 :(得分:0)
从Java 8开始,您可以在一行中初始化地图,而无需使用静态块
extension UITextField {
open override func awakeFromNib() {
super.awakeFromNib()
if UserDefaults.languageCode == "ar" {
if textAlignment == .natural {
self.textAlignment = .right
}
}
}
}
答案 10 :(得分:-1)
如果您想要默认值并且不想构建查找映射,则可以创建一个静态方法来处理它。 此示例还处理期望名称以数字开头的查找。
public static final Verbosity lookup(String name) {
return lookup(name, null);
}
public static final Verbosity lookup(String name, Verbosity dflt) {
if (StringUtils.isBlank(name)) {
return dflt;
}
if (name.matches("^\\d.*")) {
name = "_"+name;
}
try {
return Verbosity.valueOf(name);
} catch (IllegalArgumentException e) {
return dflt;
}
}
如果您需要一个辅助值,则只需像其他一些答案中一样先构建查找图即可。
答案 11 :(得分:-1)
public enum EnumRole {
ROLE_ANONYMOUS_USER_ROLE ("anonymous user role"),
ROLE_INTERNAL ("internal role");
private String roleName;
public String getRoleName() {
return roleName;
}
EnumRole(String roleName) {
this.roleName = roleName;
}
public static final EnumRole getByValue(String value){
return Arrays.stream(EnumRole.values()).filter(enumRole -> enumRole.roleName.equals(value)).findFirst().orElse(ROLE_ANONYMOUS_USER_ROLE);
}
public static void main(String[] args) {
System.out.println(getByValue("internal role").roleName);
}
}
答案 12 :(得分:-3)
您可以使用Gareth Davis&amp; Brad Mace上面,但是如果enum中没有使用的字符串,请确保处理将被抛出的Enum::valueOf()
。