2

I have switch case with 50 String checks in case as given below:

switch(str){
  case "Employee number":
    //setter
    break;
}

I want to put them in Enum with description as given below:

enum myenum{
        EMPLOYEE_NUMBER("Employee number"),
        FIRST_NAME("First name");   

        private String desc;
        private myenum(String desc) {
            this.setDesc(desc);
        }
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }

    }

Now, From Source i am getting String "Employee Number" and i want to write switch case in such a way that we can compare description of enum with incoming string input in Case.

I tried some methods in enum

myenum.valueOf(a); // This return enum value but not parameter
myenum.values // This is array which is also not useful here

Kindly suggest how it is achievable in Enum? I am using Java 8

and also suggest Is enum right choice here? or shall i create Static string class with all 50 values or any other best wayout?

2
  • @Tim: Kindly don't mark it duplicate. Neither that question and nor any of answer covers anything related to enum parameter. Kindly go through question please. I have already gone through some of threads and none of them covering this aspect. Commented Jul 25, 2019 at 4:36
  • Have you gone through this one? stackoverflow.com/a/1080912/869736 Commented Jul 25, 2019 at 4:45

1 Answer 1

4

You can first get the MyEnum instance from String str and then use switch by MyEnum, like below:

enum MyEnum {
    EMPLOYEE_NUMBER("Employee number"),
    FIRST_NAME("First name");

    private String desc;

    MyEnum(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }

    public static Optional<MyEnum> fromDesc(String desc) {
        return Stream.of(MyEnum.values()).filter(myEnum -> myEnum.getDesc().equals(desc)).findFirst();
    }

}

And then in your main code:

Optional<MyEnum> maybeMyEnum = MyEnum.fromDesc(str);
if (maybeMyEnum.isPresent()) {
    switch(maybeMyEnum.get()){
        case EMPLOYEE_NUMBER:
            //setter
            break;
    }
}


UPD 1:
As @Ole V.V. - stated in a comment, using Optional.get() and Optional.isPresent() is not a best practice - the idea is - you have to defer getting value out of Optional as much as possible. Also Optional.get() violates getter contract:

Optional.get() is an "attractive nuisance" and is too tempting for programmers, leading to frequent errors. People don't expect a getter to throw an exception.

From JDK-8140281 : (opt) add no-arg orElseThrow() as preferred alternative to get()

So given that, you can rewrite your code as:

...
MyEnum.fromDesc(str)
    .ifPresent(SomeClass::methodWithSwitchStatement);
...
class SomeClass {
    public static void methodWithSwitchStatement(MyEnum myEnum) {
        switch(myEnum){
            case EMPLOYEE_NUMBER:
               //setter
               break;
        }
    }
}
...

The names in the above code are just for examples - you shouldn't use such names in your project.


UPD 2:
Here is the version of MyEnum with caching:

enum MyEnum {
    EMPLOYEE_NUMBER("Employee number"),
    FIRST_NAME("First name");

    private static final Map<String, MyEnum> cacheByDesc;
    static {
        cacheByDesc = Stream.of(MyEnum.values()).collect(Collectors.toMap(MyEnum::getDesc, e -> e));
    }

    private String desc;

    MyEnum(String desc) {
        this.desc = desc;
    }

    public String getDesc() {
        return desc;
    }

    public static Optional<MyEnum> fromDesc(String desc) {
        return Optional.ofNullable(desc)
                .map(cacheByDesc::get);
    }

}
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks Vusal. Let me try this. Any performance overhead, if already calculated?
You can build some Map from MyEnum.values() and reduce runtime complexity of fromDesc from O(n) to O(1) - where n - is the number of entries in MyEnum, as shown here: stackoverflow.com/questions/1080904/…
Thanks. Working fine both way. I hope my lead will not say to use simple 50 Strings only in case or standard old way i.e static constant in file. :)
More conventional (and a bit shorter): maybeMyEnum.ifPresent(mEnum -> { switch (mEnum) { /* … */ } });. Rule of thumb: rarely use isPresent and get, they are low-level.
Yeah, you can add a Map from string to enum constant, or you implement fromDesc with a switch statement…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.