Switch on Enum in Java

Java Switch on Enum Value

You need to introduce a method to fetch the enum constant based on the value passed in :

public static Week fetchValue(String constant) {
for (Week week : Week.values()) {
if (week.value.equals(constant)) {
return week;
}
}
return null;
}

Now use it like :

Week weekday = Week.fetchValue(userInput);
if (weekday != null) {
switch (week ) {

// rest of the code

}
} else {
System.out.println("Incorrect input");
}

Compare string with enum value using switch in Java

You can use java.lang.String values in your java.lang.Enum and test against it in your switch cases.

But, like @SpencerSprowls said in comments, it will throw an java.lang.IllegalArgumentException if you use a value that doesn't match with any values of your java.lang.Enum.

Thus, adding a default case in your switch is useless. To avoid throwing unwanted exceptions, you can convert your java.lang.Enum values to an java.util.EnumMap and check if it matches existing values before the switch with EnumMap#containsValue

private enum PickerActions {
PICK("PICK"),
PICK_MULTIPLE("PICK_MULTIPLE");
private final String value;
PickerActions(final String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}

private static boolean test(String test) {
switch (PickerActions.valueOf(test)) {
case PICK:
//
return true;
case PICK_MULTIPLE:
//
return false;
// default:
// This will never happen
// return false;
}
}

Here is a working example

Why can't I use enums for switch-case-statements?

Case labels have to be compile time constant expressions. A method call is not one of those.

What you can do is change test into a Cons. Then you can use it in switch:

Cons test;

// some code

switch(test) {
case Cons.ONE:
// ...
break;
case Cons.TWO:
// ...
break;
default:
// ...
}

If you must work with an int, create a method that returns the correct enum instance using the value.

Cons lookUpByVal(int test) { ... }

switch(lookUpByVal(test)) {
case Cons.ONE:
...

Java using enum with switch statement

The part you're missing is converting from the integer to the type-safe enum. Java will not do it automatically. There's a couple of ways you can go about this:

  1. Use a list of static final ints rather than a type-safe enum and switch on the int value you receive (this is the pre-Java 5 approach)
  2. Switch on either a specified id value (as described by heneryville) or the ordinal value of the enum values; i.e. guideView.GUIDE_VIEW_SEVEN_DAY.ordinal()
  3. Determine the enum value represented by the int value and then switch on the enum value.

    enum GuideView {
    SEVEN_DAY,
    NOW_SHOWING,
    ALL_TIMESLOTS
    }

    // Working on the assumption that your int value is
    // the ordinal value of the items in your enum
    public void onClick(DialogInterface dialog, int which) {
    // do your own bounds checking
    GuideView whichView = GuideView.values()[which];
    switch (whichView) {
    case SEVEN_DAY:
    ...
    break;
    case NOW_SHOWING:
    ...
    break;
    }
    }

    You may find it more helpful / less error prone to write a custom valueOf implementation that takes your integer values as an argument to resolve the appropriate enum value and lets you centralize your bounds checking.

How to ensure that a switch/case statement has all the options like using enum?

If you are asking whether you can create an enum where the constants have spaces, then the answer is 'no'.

Enum constants are normal Java identifiers, like class or variable names so they can not have spaces or special characters in them.


However is it impossible to link an enum with a String? No.

If for some reason you want your switch case to use an enum for readability/brevity, but your inputs are Strings that can have spaces, dots, special characters..., then there is a way.

You need to extend your enum to have an extra field (let's call it label) to hold this String.

In your method with the switch case that uses the enum, you can call a findByLabel method

that returns the enum that corresponds to the provided String.

Here is a little example class that uses your enum values NORTH, EAST, SOUTH, WEST,

linked to Strings of different (invalid enum naming) structures.

public class EnumExample {

enum SwitchEnum {
NORTH ("North star"),
EAST ("Eastpack rulez!"),
SOUTH ("https://www.southafrica.net/"),
WEST ("java.awt.BorderLayout.WEST");

private final String label;
SwitchEnum(final String label) {
this.label = label;
}

@Override
public String toString() {
return this.label;
}

private static final Map<String,SwitchEnum> map;
static {
map = new HashMap<String,SwitchEnum>();
for (SwitchEnum v : SwitchEnum.values()) {
map.put(v.label, v);
}
}
public static SwitchEnum findByLabel(String label) {
return map.get(label);
}
}

public static String doEnumSwitch(String enumString) {
SwitchEnum enm = SwitchEnum.findByLabel(enumString);
if (enm != null) {
String enumReturn = enm.name() +" : "+ enm;
switch (enm) {
case NORTH:
return enumReturn +" - Up there.";
case EAST:
return enumReturn +" - Now for sale.";
case SOUTH:
return enumReturn +" - Now with 50% more elephants.";
default:
return "UNHANDLED ENUM : "+ enm.name() +" - "+ enm;
}
} else {
return "UNKNOWN ENUM : "+ enumString;
}
}

public static void main(String[] args) {
System.out.println(doEnumSwitch("North star"));
System.out.println(doEnumSwitch("Eastpack rulez!"));
System.out.println(doEnumSwitch("https://www.southafrica.net/"));
System.out.println(doEnumSwitch("java.awt.BorderLayout.WEST"));
System.out.println(doEnumSwitch("I only want to get out of here."));
}
}

This outputs the following

NORTH : North star - Up there.

EAST : Eastpack rulez! - Now for sale.

SOUTH : https://www.southafrica.net/ - Now with 50% more elephants.

UNHANDLED ENUM : WEST - java.awt.BorderLayout.WEST

UNKNOWN ENUM : I only want to get out of here.

What is the usage of default when the switch is for an enum?

It is good practice to throw an Exception as you have shown in the second example. You improve the maintainability of your code by failing fast.

In this case it would mean if you later (perhaps years later) add an enum value and it reaches the switch statement you will immediately discover the error.

If the default value were not set, the code would perhaps run through even with the new enum value and could possibly have undesired behavior.

Trying to replace a switch statement with an enum in Java

If you want the EmployeeTableColumn enum to control how you extract information from an EmployeeData object, then you need a method in EmployeeTableColumn that takes your EmployeeData as a parameter and returns the extracted information.

public enum EmployeeTableColumn {
NAME {
@Override
public Object getData(EmployeeData data) {
return data.getName();
}
},
DESCRIPTION {
@Override
public Object getData(EmployeeData data) {
return data.getDescription();
}
},
CONTRIBUTION {
@Override
public Object getData(EmployeeData data) {
return data.getAddress();
}
};

public abstract Object getData(EmployeeData data);
}

Then you can write a method that uses an EmployeeTableColumn to extract the correct data.

public Object getValueAt(int row, int col) {
EmployeeData employeeData = (EmployeeData)items.get(row);

// however you are going to pick the right column object
EmployeeTableColumn employeeColumn = EmployeeTableColumn.values()[col];

return employeeColumn.getData(employeeData);
}


Related Topics



Leave a reply



Submit