简体   繁体   中英

How do I switch on values defined inside a java enum of strings

I have the following code :

class MyClass {
    private Value value;
    public enum Value {
        INSERT_ONLY("INSERT_ONLY"), UPDATE_ONLY("UPDATE_ONLY"), UPSERT("UPSERT") ;
        private final String val ;
        private Value(final String v) {val = v ;}
        public String toString() {return val ;}     
        public String getVal() {
            return val;
        }
    } ;
    public Value getValue() {
        return value;
    }
    public void setValue(Value value) {
        this.value = value;
    }
}

public class one {
    public static void main(String[] args) {
        MyClass obj = new MyClass() ;
        obj.setValue(MyClass.Value.INSERT_ONLY) ;

        String s = obj.getValue().toString() ;
        String s1 = MyClass.Value.INSERT_ONLY.toString() ;
        switch(s) {
            case "INSERT_ONLY" : System.out.println("INSERT_ONLY") ;
                break ;
            case "s2" : System.out.println("s2") ;
                break ;
        }
    }
}

This code works. But what I want is that in switch-case I use the strings as defined in the enum Value . If I use s1 in case , it generates an error. What is the way out?

Enums have a method .name() that returns the enum as a String. All your "values" are equivalent to this - just switch on that.

You can delete the value field, the constructor and getter and call name() where you are currently calling getValue() .

Further, the default implementation of toString() returns name() so you can delete your toString() method without having any effect.

Finally, you can switch on the enum itself.

you string in the enum is actually the same as the enumertor constants... so it is a little redundant and completely unnescessary...

try this:

enum Value {
    INSERT_ONLY, UPDATE_ONLY, UPSERT;
}

public static void main(String[] args)  {
Week obj = new Week() ;
Value s = obj.getValue( ) ;
        switch(s) {
            case INSERT_ONLY : System.out.println("INSERT_ONLY") ;
                break ;
            case UPDATE_ONLY : System.out.println("UPDATE_ONLY") ;
                break ;
        }
    }
}

You could try it this way:

MyClass.Value value = obj.getValue() ;
switch(value) {
  case INSERT_ONLY : System.out.println("INSERT_ONLY") ;
    break ;
  case UPSERT : System.out.println("Upsert") ;
    break ;
  case UPDATE_ONLY : System.out.println("Update only") ;
   break ;
 }

Basically, the switch-statement uses the enum-names. So there is no need to apply the toString() -method on the Value returned by obj.getValue() .

If you would like to know why switch will not work in combination with strings, please have a look here . One more suggestion: add also the default-branch to the switch-statement.

If I understand correctly, you're trying to look up an enum constant by an unknown string s . The reason your case expression can't be s1 is because it must be a compile-time constant , which s1 is not. Since your example seems to be mostly theoretical, I'll suggest a few options and you can pick the most appropriate for your actual case:

  1. Assuming the enum names are the same as their value s (in which case you can scrap the field entirely) and you're just trying to look up an enum by its name, just do this:

     MyClass.Value v = MyClass.Value.valueOf(s); 

    This will throw an IllegalArgumentException if no mapping is found for s1 .

  2. Still assuming the names are the same, but you do need an actual switch with some additional cases and custom logic:

     try { MyClass.Value v = MyClass.Value.valueOf(s); switch (v) { case INSERT_ONLY : System.out.println("INSERT_ONLY") ; break ; } } catch (IllegalArgumentException e) { switch (s) case "s2" : System.out.println("s2") ; break ; } } 
  3. If the names are not actually the same, you can add a static map of constants inside the enum class, to simulate valueOf() :

     public enum Value { ONLY_INSERT("ONLY_INSE"), ONLY_UPDATE("UPDATE_ONLY"), UPSERT("UPSERT") ; private static final Map<String, Value> byName = new HashMap<>(); static { for (Value v : values()) { byName.put(v.getVal(), v); } } public static Value byName(String name) { Value result = byName.get(name); if (result == null) { throw new IllegalArgumentException("Invalid name" + name); } return result; } private final String val ; private Value(final String v) {val = v ;} public String toString() {return val ;} public String getVal() { return val; } } ; 

    Now you can do the same as the previous solutions, using MyClass.Value.byName() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM