I have two enum classes one is external and the other is internal.
public enum ExternalEnum
{
EXTERNAL_CAR, EXTERNAL_VAN, EXTERNAL_BUS
}
public enum InternalEnum
{
CAR, VAN, BUS
}
I need to map internal to external and external to internal. So I have done the following,
public class EnumMapper
{
public ExternalEnum toExternal(InternalEnum internalEnum)
{
switch (internalEnum)
{
case BUS:
return ExternalEnum.EXTERNAL_BUS;
case CAR:
return ExternalEnum.EXTERNAL_CAR;
case VAN:
return ExternalEnum.EXTERNAL_VAN;
}
return null;
}
public InternalEnum toInternal(ExternalEnum externalEnum)
{
switch (externalEnum)
{
case EXTERNAL_BUS:
return InternalEnum.BUS;
case EXTERNAL_CAR:
return InternalEnum.CAR;
case EXTERNAL_VAN:
return InternalEnum.VAN;
}
return null;
}
}
So same kind of mapping is repeating in two methods. Isn't there a good approach to achieve this using less amount of code?
InternalEnum.values()[ externalEnum.ordinal() ]
Assuming the equivalent enum objects are declared in the same order, we can retrieve one enum object from the other by accessing the array of all enum objects returned from a call to the implicit public static T[] values() method (see this Question) and access by zero-based index number retrieved from the misnamed Enum#ordinal method.
For example, InternalEnum.values() returns an array of all the enum objects in the order in which they were declared. Then we use array accessor […] to retrieve the object matching the index number of its mate in the other enum.
InternalEnum internalEnum = InternalEnum.values()[ externalEnum.ordinal() ] ;
And vice versa:
ExternalEnum externalEnum = ExternalEnum.values()[ internalEnum.ordinal() ] ;
Here is example usage. Bonus tip: In Java 16+, we can declare an enum locally — see JEP 395: Records.
enum ExternalEnum { EXTERNAL_CAR, EXTERNAL_VAN, EXTERNAL_BUS }
enum InternalEnum { CAR, VAN, BUS }
System.out.println(
InternalEnum.values()[ ExternalEnum.EXTERNAL_VAN.ordinal() ]
);
System.out.println(
ExternalEnum.values()[ InternalEnum.VAN.ordinal() ]
);
VAN
EXTERNAL_VAN
The answer from Basil Bourque is good, but I do not like to use ordinal() because you can easily rotate the enum constants and business logic will be broken.
You did almost correct, just remember, that enum constant is a plain old java class instance and it can be expanded with additional functionality. Therefore it's better to hide all mapper logic inside an enum.
public enum ExternalEnum {
EXTERNAL_CAR,
EXTERNAL_VAN,
EXTERNAL_BUS
}
public enum InternalEnum {
CAR(ExternalEnum.EXTERNAL_CAR),
VAN(ExternalEnum.EXTERNAL_VAN),
BUS(ExternalEnum.EXTERNAL_BUS);
private final ExternalEnum externalEnum;
InternalEnum(ExternalEnum externalEnum) {
this.externalEnum = externalEnum;
}
public ExternalEnum toExternal() {
return externalEnum;
}
public static Optional<InternalEnum> parseExternal(ExternalEnum externalEnum) {
for (InternalEnum internalEnum : values())
if (internalEnum.externalEnum == externalEnum)
return Optional.of(internalEnum);
return Optional.empty();
}
}
Demo
ExternalEnum externalEnum = ExternalEnum.EXTERNAL_CAR;
Optional<InternalEnum> optInternalEnum = InternalEnum.parseExternal(externalEnum);
System.out.println(externalEnum);
System.out.println(optInternalEnum.orElse(null));
System.out.println(optInternalEnum.map(InternalEnum::toExternal).orElse(null));
An alternative is to have only a Mapper
public final class EnumMapper {
private final Map<ExternalEnum, InternalEnum> MAP_EXT_INT = Map.of(
ExternalEnum.EXTERNAL_CAR, InternalEnum.CAR,
ExternalEnum.EXTERNAL_VAN, InternalEnum.VAN,
ExternalEnum.EXTERNAL_BUS, InternalEnum.BUS);
private final Map<InternalEnum, ExternalEnum> MAP_INT_EXT = Map.of(
InternalEnum.CAR, ExternalEnum.EXTERNAL_CAR,
InternalEnum.VAN, ExternalEnum.EXTERNAL_VAN,
InternalEnum.BUS, ExternalEnum.EXTERNAL_BUS);
public static ExternalEnum toExternal(InternalEnum internalEnum) {
return MAP_INT_EXT.get(internalEnum);
}
public InternalEnum toInternal(ExternalEnum externalEnum) {
return MAP_EXT_INT.get(externalEnum);
}
private EnumMapper() {}
}
public enum ExternalEnum {
EXTERNAL_CAR,
EXTERNAL_VAN,
EXTERNAL_BUS
}
public enum InternalEnum {
CAR,
VAN,
BUS;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With