Problem
We have multiple enum types that have some public static EnumType valueOfText(String text)
, for the purpose of mapping the contents of a data file cell to enum.
I'm trying to write a generic enum util that takes a comma-separated string and return multiple enum values. For example, we have the following enum:
public enum Frequency {
SEMI_ANNUAL("S"), MONTHLY("M"), QUARTERLY("Q"), ANNUAL("A")
public final String textValue;
public Frequency(String textValue) {
this.textValue = textValue;
}
public static Frequency valueOfText(String textValue) {
for (Frequency frequency : values()) {
if (frequency.textValue.equals(textValue))
return frequency;
}
return null;
}
}
and string "A,S"
which we want to convert to [Frequency.ANNUAL, Frequency.SEMI_ANNUAL]
.
Attempted solution
I create some EnumUtils
like so:
import java.util.stream.Collectors
public final class EnumUtils {
public static final String LIST_SEPARATOR = ",";
public static <E extends Enum<E>> List<E> CreateFromText(String text) {
List<String> textList = text.split(this.LIST_SEPARATOR)
return textList.stream()
.map { txt ->
E.valueOfText(txt)
}
.collect(Collectors.toList())
}
}
What happen after said solution
We go to use it, like this:
EnumUtils.CreateFromText<Frequency>(row[3])
and the IDE compain, immediately, about the <>
.
How can we specify enum type in this?
CodePudding user response:
In Groovy you can do it if you pass the actual Class
instead of just using a type parameter.
enum Frequency {
SEMI_ANNUAL("S"), MONTHLY("M"), QUARTERLY("Q"), ANNUAL("A")
final String textValue;
Frequency(String textValue) {
this.textValue = textValue;
}
static Frequency valueOfText(String textValue) {
return values().find { it.textValue == textValue }
}
}
final class EnumUtils {
static <E extends Enum<E>> List<E> createFromText(Class<E> clazz, String text) {
return text.split(",").collect { clazz.valueOfText(it) }
}
}
EnumUtils.createFromText(Frequency, "S,M")
The same idea won't work in Java, since clazz
won't have valueOfText
at compile time.
Perhaps the Util class doesn't save you much typing, though:
"S,M".split(",").collect(Frequency.&valueOfText)