1

What is the right way of getting the enum by it's constructor value in java? Here's an example:

public enum Status{
CREATED("created"), IN_PROGRESS("inProgress"), COMPLETED("completed");

public final String statusStr;
Status(String statusStr){
  this.statusStr = statusStr;
}
}

So if the input I get is a string of 'created' how do I get Status.CREATED from it?

  • Not a full duplicate, but take a look at https://stackoverflow.com/questions/1080904/how-can-i-lookup-a-java-enum-from-its-string-value either loop over values or build a lookup map – Lesiak Mar 20 '20 at 21:24
  • Consider using `valueOf` instead of creating your own parallel string lookup method. I think it's sane to drop the naming conventions for Java constants here and go with `created`, `inProgress` and so on as enum values. I gave this advice before here: https://stackoverflow.com/questions/12639791/what-is-the-reason-for-java-lang-illegalargumentexception-no-enum-const-class-e/12639829#12639829 – Costi Ciudatu Mar 20 '20 at 21:47

1 Answers1

2

I don't think you can do it automatically. You will have to create a static method for that:

public static Status fromString(String string) {
    for (Status status : values()) {
        if (status.statusStr.equals(string)) {
            return status;
        }
    }
    throw new IllegalArgumentException(string);
}

Incorporating @Pshemo's suggestions, the code could also be:

@RequiredArgsConstructor @Getter
public enum Status {
    CREATED("created"), IN_PROGRESS("inProgress"), COMPLETED("completed");

    private static final Map<String, Status> MAP = Arrays.stream(Status.values())
            .collect(Collectors.toMap(Status::getStatusStr, Function.identity()));

    private final String statusStr;

    public static Status fromString(String string) {
        return Objects.requireNonNull(MAP.get(string));
    }
}
Christophe L
  • 13,725
  • 6
  • 33
  • 33
  • 3
    Possible improvement: each call of `values()` creates fresh array of Status enum values, and those arrays will always have same Status elements. We can call `values()` once and cache it like `private static final Status[] VALUES = values();` and use `VALUES` in method instead. We can also use `Map` as cache. Simply fill it in static initialization block and use it like `public static Status fromString(String string) { return map.get(string); }`. – Pshemo Mar 20 '20 at 21:34