可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The values in my enum are words that need to have spaces in them, but enums can't have spaces in their values so it's all bunched up. I want to override toString() to add these spaces where I tell it to.
I also want the enum to provide the correct enum when I use valueOf() on the same string that I added the spaces to.
For example:
public enum RandomEnum { StartHere, StopHere }
Call toString() on RandomEnum whose value is StartHere returns string "Start Here". Call valueof() on that same string ("Start Here") returns enum value StartHere.
How can I do this?
回答1:
You can try out this code. Since you cannot override valueOf method you have to define a custom method (getEnum in the sample code below) which returns the value that you need and change your client to use this method instead.
public enum RandomEnum { StartHere("Start Here"), StopHere("Stop Here"); private String value; RandomEnum(String value) { this.value = value; } public String getValue() { return value; } @Override public String toString() { return this.getValue(); } public static RandomEnum getEnum(String value) { for(RandomEnum v : values()) if(v.getValue().equalsIgnoreCase(value)) return v; throw new IllegalArgumentException(); } }
回答2:
Try this, but i don't sure that will work every where :)
public enum MyEnum { A("Start There"), B("Start Here"); MyEnum(String name) { try { Field fieldName = getClass().getSuperclass().getDeclaredField("name"); fieldName.setAccessible(true); fieldName.set(this, name); fieldName.setAccessible(false); } catch (Exception e) {} } }
回答3:
How about a Java 8 implementation? (null can be replaced by your default Enum)
public static RandomEnum getEnum(String value) { List list = Arrays.asList(RandomEnum.values()); return list.stream().filter(m -> m.value.equals(value)).findAny().orElse(null); }
Or you could use:
...findAny().orElseThrow(NotFoundException::new);
回答4:
You can use a static Map in your enum that maps Strings to enum constants. Use it in a 'getEnum' static method. This skips the need to iterate through the enums each time you want to get one from its String value.
public enum RandomEnum { StartHere("Start Here"), StopHere("Stop Here"); private final String strVal; private RandomEnum(String strVal) { this.strVal = strVal; } public static RandomEnum getEnum(String strVal) { if(!strValMap.containsKey(strVal)) { throw new IllegalArgumentException("Unknown String Value: " + strVal); } return strValMap.get(strVal); } private static final Map strValMap; static { final Map tmpMap = Maps.newHashMap(); for(final RandomEnum en : RandomEnum.values()) { tmpMap.put(en.strVal, en); } strValMap = ImmutableMap.copyOf(tmpMap); } @Override public String toString() { return strVal; } }
Just make sure the static initialization of the map occurs below the declaration of the enum constants.
BTW - that 'ImmutableMap' type is from the Google guava API, and I definitely recommend it in cases like this.
EDIT - Per the comments:
- This solution assumes that each assigned string value is unique and non-null. Given that the creator of the enum can control this, and that the string corresponds to the unique & non-null enum value, this seems like a safe restriction.
- I added the 'toSTring()' method as asked for in the question
回答5:
I don't think your going to get valueOf("Start Here") to work. But as far as spaces...try the following...
static private enum RandomEnum { R("Start There"), G("Start Here"); String value; RandomEnum(String s) { value = s; } } System.out.println(RandomEnum.G.value); System.out.println(RandomEnum.valueOf("G").value); Start Here Start Here
回答6:
The following is a nice generic alternative to valueOf()
public static RandomEnum getEnum(String value) { for (RandomEnum re : RandomEnum.values()) { if (re.description.compareTo(value) == 0) { return re; } } throw new IllegalArgumentException("Invalid RandomEnum value: " + value); }
回答7:
You still have an option to implement in your enum this:
public static > T valueOf(Class enumType, String name){...}