programing tip

Java 열거 형에서 valueof () 및 toString () 재정의

itbloger 2020. 7. 25. 10:41
반응형

Java 열거 형에서 valueof () 및 toString () 재정의


내 값 enum은 공백이 있어야하는 단어이지만 열거 형은 값에 공백을 가질 수 없으므로 모두 묶입니다. 내가 toString()말한 곳에이 공간을 추가 하기 위해 재정의하고 싶습니다 .

또한 valueOf()공백을 추가 한 동일한 문자열에서 사용할 때 열거 형이 올바른 열거 형을 제공하기를 원합니다 .

예를 들면 다음과 같습니다.

public enum RandomEnum
{
     StartHere,
     StopHere
}

전화 toString()RandomEnum그 값이 StartHere반환 문자열 "Start Here". valueof()동일한 문자열을 호출 하면 "Start Here"열거 형 값이 반환 StartHere됩니다.

어떻게해야합니까?


이 코드를 시험해 볼 수 있습니다. valueOf메소드를 대체 할 수 없으므로 getEnum필요한 값을 리턴하고이 메소드를 대신 사용하도록 클라이언트를 변경 하는 사용자 정의 메소드 ( 아래 샘플 코드에서) 를 정의 해야합니다.

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();
    }
}

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) {}
    }
}

How about a Java 8 implementation? (null can be replaced by your default Enum)

public static RandomEnum getEnum(String value) {
    List<RandomEnum> 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);

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<String, RandomEnum> strValMap;
    static {
        final Map<String, RandomEnum> 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:

  1. 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.
  2. I added the 'toSTring()' method as asked for in the question

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

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);
}

You still have an option to implement in your enum this:

public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name){...}

참고URL : https://stackoverflow.com/questions/9662170/override-valueof-and-tostring-in-java-enum

반응형