I am making a card game with a friend and I decided to make a card viewer, we input the all of card details into a text document and my program reads each card in, line by line.
Different types of card have different properties, all properties are represented in some type of enum.
I have some code which converts lists of strings into lists of enum properties. Example Enums:
public enum Race{
ELVES, HUMANS, DWARFS
}
public enum Rarity{
COMMON, UNCOMMON, RARE
}
Assuming a card can have multiple Races and multiple rarities I want to make a method that can take a list of strings and a type of enum and return a list of enum values, eg
// Take in an array of strings and a type of Enum value to convert them to
public <Type extends Enum<Type>> Type[] getValues(String[] strings){
// Make an array to hold the enum values
Type[] values = new Type[strings.length];
// For each string, convert it into an enum value and add it to the array
for (int i = 0; i < strings.lenght; i++)
values[i] = Type.valueOf(strings[i]);
return values;
}
I know this method doesn't work, but I hope it portrays at least what I am trying to do, I'd like a method to which I can send any list of strings and it will convert them into a list of EnumValues, eg convert the strings {"ELVES", HUMANS"} to the relevant Race values {ELVES, HUMANS}.
You might ask why I don't just make separate methods like
convertRaceStings(String[] strings){//method workings here}
convertRarityStings(String[] strings){//method workings here}
unfortunately the two enums used here are simple examples, there are a lot more enums which would each require another method.
You should use an EnumSet instead of an array of enums. It is more memory efficient. As a bonus you won't have to mess with generics arrays.
Your method will then look like:
private static <T extends Enum<T>> EnumSet<T> createEnumSet(Class<T> clazz, String... values) {
EnumSet<T> set = EnumSet.noneOf(clazz);
for(String value : values) {
set.add(Enum.valueOf(clazz, value));
}
return set;
}
Well except if you need to have multiple instance of the same enum.
Usage:
final EnumSet<Race> races = createEnumSet(Race.class, "HUMANS", "DWARFS");
It would be easier if you passed the enum type as well - that would enable you to use the Enum#valueOf
static method :
public static void main(String[] args) {
System.out.println(get("ELVES", Race.class));
System.out.println(get("COMMON", Rarity.class));
}
public static <T extends Enum<T>> T get(String value, Class<T> clazz) {
return Enum.valueOf(clazz, value);
}
public static enum Race {
ELVES, HUMANS, DWARFS
}
public static enum Rarity {
COMMON, UNCOMMON, RARE
}
If you don't want to pass the enum class as a second argument, you will need to maintain a mapping somewhere.
Working with arrays is somewhat annoying in generic code.
@SuppressWarnings("unchecked")
public <E extends Enum<E>> E[] getValues(Class<E> clazz, String[] strings) {
E[] result = (E[])java.lang.reflect.Array.newInstance(clazz, strings.length);
for (int i = 0; i < strings.length; ++i) {
result[i] = Enum.valueOf(clazz, strings[i]);
}
return result;
}
This should work.
Enums in Java are very powerful. Since enumerations are constant and cannot be dynamically added, you could do something like this:
public enum Race {
ELVES, HUMANS, DWARFS;
public static Race getValue(String name) {
switch (name.toLowerCase()) {
case "evles": return EVLES;
case "humans": return HUMANS;
case "dwarfs": return DWARFS;
default: throw new Exception();
}
}
}
This assumes you're using Java 7, but if not, replace the switch with else-if statements.
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.