Consider I have many enums (Java) that looks somewhat like this:
@AllArgsConstructor
@Getter
public enum PopularPeriod {
MONTHLY ("MON"),
BIMONTHLY ("BMN"),
QUARTERLY ("QTR"),
SEMI_ANNUALLY ("SMA"),
ANNUALLY ("ANL");
private final String value;
}
Now, a usual use, I'd think, would be to get the enum object using its value (the string) - there's an input you're parsing and you want to turn the string into some nice objects that make the code more readable.
So I added this to the enum above -
public static PopularPeriod fromString(String value) {
for (PopularPeriod pp : PopularPeriod.values()) {
if (pp.getValue().equalsIgnoreCase(value)) return pp;
}
return null;
}
(don't mind the returning of null the casing). This works quite good. But if you have dozens of those enums - you need to write it for each one.
I tried approaches like adding something like this to a utility class -
public static <T extends Enum<T>> T safeEnumByValue(Class<T> enumType, Object value) { ... }
but there I don't know of the private field (value).
So I though of "implementing" an interface instead (as enum may not extend base classes), and make the search as a default method in the interface.
public interface IEnum<T> {
T getValue();
}
@AllArgsConstructor
@Getter
public enum PopularPeriod implements IEnum<String> { ... }
and adding a default method in the interface - but that's impossible as I don't have the PopularPeriod.values()
there to work with.
In the end, I combined the two approaches. I have this method in a utility class:
public static <T extends IEnum> T safeEnumByValue(Class<T> enumType, Object value) {
for (T enumConstant : enumType.getEnumConstants()) {
if (enumConstant.getValue().equals(value)) return enumConstant;
}
return null;
}
Just got there.
It works.
I thought maybe I'd delete this question,but I would love to hear if there's any elegant way to do it.