如何将字符串存储到枚举类映射中

huangapple go评论112阅读模式
英文:

How can we store String to Enum classes map

问题

I have multiple enum classes . For example

public class enum Animal {
DOG,
LION;
}
public class enum Bird {

OSTRICH,
CROW };
}
I want to have a Map<String, Enums > where i can store these enum classes as values and then fetch them based on keys . For example
Map<String, Enumclass> such that it gives me the Enum when i pass the key to the Map. For example map.get("Animal") should return me the enum Animal and then i can do operations like Animals.valueOf();

I was able to store the enums in a private Map<String, Class<? extends Enum>> Map; but not able to retreive and cast it back to the proper enum classes. Is it possible to do this

英文:

I have multiple enum classes . For example

   public class enum Animal { 
        DOG,
        LION;
} 
    public class enum Bird { 

     OSTRICH,
     CROW };
}

I want to have a Map<String, Enums > where i can store these enum classes as values and then fetch them based on keys . For example
Map<String, Enumclass> such that it gives me the Enum when i pass the key to the Map. For example map.get("Animal") should return me the enum Animal and then i can do operations like Animals.valueOf();

I was able to store the enums in a private Map&lt;String, Class&lt;? extends Enum&gt;&gt; Map; but not able to retreive and cast it back to the proper enum classes. Is it possible to do this

答案1

得分: 3

You will need to have your enums implement a common interface like so:

import java.util.*;

public class Zoo {
    private static final Map<String, ZooAnimal> animals;

    static {
        Map<String, ZooAnimal> tmp = new HashMap<>();
        tmp.put("CHEETAH", Cat.CHEETAH);
        tmp.put("LION", Cat.LION);
        tmp.put("PANTHER", Cat.PANTHER);
        tmp.put("TIGER", Cat.TIGER);
        tmp.put("HAWK", Bird.HAWK);
        tmp.put("OSTRICH", Bird.OSTRICH);
        tmp.put("OWL", Bird.OWL);
        animals = Collections.unmodifiableMap(tmp);
    }

    public static void main(String[] args) {
        ZooAnimal animal = animals.get("PANTHER");
        if (animal != null && animal instanceof Cat) {
            // A panther is a cat
            System.out.printf("A %s is a cat%n", animal.getName().toLowerCase());
        }
    }

    private interface ZooAnimal {
        String getName();
    }

    public enum Cat implements ZooAnimal {
        CHEETAH, LION, PANTHER, TIGER;

        @Override
        public String getName() {
            return this.name();
        }
    };

    public enum Bird implements ZooAnimal {
        HAWK, OSTRICH, OWL;

        @Override
        public String getName() {
            return this.name();
        }
    };
}

If you want the values, you can use the generic Enum class:

import java.util.*;

public class Zoo {
    private static final Map<String, Class<? extends Enum<?>>> animals;

    static {
        Map<String, Class<? extends Enum<?>>> tmp = new HashMap<>();
        tmp.put("BIRD", Bird.class);
        tmp.put("CAT", Cat.class);
        animals = Collections.unmodifiableMap(tmp);
    }

    public static void main(String[] args) {
        Class<? extends Enum<?>> animal = animals.get("CAT");
        // Print the values
        for (Enum<?> c : animal.getEnumConstants()) {
            System.out.println(c.name()); // CHEETAH, LION, PANTHER, TIGER
        }
    }

    public enum Cat {
        CHEETAH, LION, PANTHER, TIGER;
    };

    public enum Bird {
        HAWK, OSTRICH, OWL;
    };
}
英文:

You will need to have your enums implement a common interface like so:

import java.util.*;

public class Zoo {
    private static final Map&lt;String, ZooAnimal&gt; animals;

    static {
        Map&lt;String, ZooAnimal&gt; tmp = new HashMap&lt;&gt;();
        tmp.put(&quot;CHEETAH&quot;, Cat.CHEETAH);
        tmp.put(&quot;LION&quot;, Cat.LION);
        tmp.put(&quot;PANTHER&quot;, Cat.PANTHER);
        tmp.put(&quot;TIGER&quot;, Cat.TIGER);
        tmp.put(&quot;HAWK&quot;, Bird.HAWK);
        tmp.put(&quot;OSTRICH&quot;, Bird.OSTRICH);
        tmp.put(&quot;OWL&quot;, Bird.OWL);
        animals = Collections.unmodifiableMap(tmp);
    }

    public static void main(String[] args) {
        ZooAnimal animal = animals.get(&quot;PANTHER&quot;);
        if (animal != null &amp;&amp; animal instanceof Cat) {
            // A panther is a cat
            System.out.printf(&quot;A %s is a cat%n&quot;, animal.getName().toLowerCase());
        }
    }

    private interface ZooAnimal {
        String getName();
    }

    public enum Cat implements ZooAnimal {
        CHEETAH, LION, PANTHER, TIGER;

        @Override
        public String getName() {
            return this.name();
        }
    };

    public enum Bird implements ZooAnimal {
        HAWK, OSTRICH, OWL;

        @Override
        public String getName() {
            return this.name();
        }
    };
}

If you want the values, you can use the generic Enum class:

import java.util.*;

public class Zoo {
    private static final Map&lt;String, Class&lt;? extends Enum&lt;?&gt;&gt;&gt; animals;

    static {
        Map&lt;String, Class&lt;? extends Enum&lt;?&gt;&gt;&gt; tmp = new HashMap&lt;&gt;();
        tmp.put(&quot;BIRD&quot;, Bird.class);
        tmp.put(&quot;CAT&quot;, Cat.class);
        animals = Collections.unmodifiableMap(tmp);
    }

    public static void main(String[] args) {
        Class&lt;? extends Enum&lt;?&gt;&gt; animal = animals.get(&quot;CAT&quot;);
        // Print the values
        for (Enum&lt;?&gt; c : animal.getEnumConstants()) {
            System.out.println(c.name()); // CHEETAH, LION, PANTHER, TIGER
        }
    }

    public enum Cat {
        CHEETAH, LION, PANTHER, TIGER;
    };

    public enum Bird {
        HAWK, OSTRICH, OWL;
    };
}

答案2

得分: 0

* 更新我的答案,因为问题附带了更多解释。

我将提供另一种方法,即向枚举添加另一个维度以指示动物类型,在这种情况下,您无需转换为多个枚举:

public enum AnimalType
{
    BIRD, CAT;
}
public enum Animal
{
    CHEETAH(AnimalType.CAT, &quot;猎豹&quot;),
    LION(AnimalType.CAT, &quot;狮子&quot;),
    HAWK(AnimalType.BIRD, &quot;&quot;),
    OWL(AnimalType.BIRD, &quot;猫头鹰&quot;);

    private AnimalType type;
    private String name;

    Animal(AnimalType type, String name) {
        this.type = type;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public AnimalType getType() {
        return type;
    }

    public static Optional&lt;Animal&gt; fromName(String name) {
        return Arrays.stream(Animal.values())
            .filter(a -&gt; a.name.equals(name))
            .findFirst();
    }

    public static List&lt;Animal&gt; fromType(AnimalType type) {
        return Arrays.stream(Animal.values())
            .filter(a -&gt; a.type == type))
            .collect(Collectors.toList());
    }
}
英文:

* Updating my answer since the question is updated with more explanations.

I'm going to provide another approach which is adding another dimension to the Enum to indicate the Animal type, and in this case you don't need to cast to multiple Enums:

public enum AnimalType 
{
    BIRD, CAT;
}
public enum Animal 
{
    CHEETAH(AnimalType.CAT, &quot;Cheetah&quot;),
    LION(AnimalType.CAT, &quot;Lion&quot;),
    HAWK(AnimalType.BIRD, &quot;Hawk&quot;),
    OWL(AnimalType.BIRD, &quot;Owl&quot;);
 
    private AnimalType type;
    private String name;
 
    Animal(AnimalType type, String name) {
        this.type = type;
        this.name = name;
    }
 
    public String getName() {
        return name;
    }

    public AnimalType getType() {
        return type;
    }

    public static Optional&lt;Animal&gt; fromName(String name) {
        return Arrays.stream(Animal.values())
            .filter(a -&gt; a.name.equals(name))
            .findFirst();
    }

    public static List&lt;Animal&gt; fromType(AnimalType type) {
        return Arrays.stream(Animal.values())
            .filter(a -&gt; a.type == type))
            .collect(Collectors.toList());
    }
}

答案3

得分: 0

以下是翻译好的部分:

  • "There doesn't appear to be an exact solution to what you're looking to achieve." -> "似乎没有确切的解决方案来实现你所希望的。"
  • "Essentially, I believe that since an enum is considered a static object, you cannot cast the static reference into a new object." -> "基本上,我认为由于 enum 被视为 static 对象,你无法将静态引用转换为新对象。"
  • "You would have to use a Class<Animal> type." -> "你需要使用 Class<Animal> 类型。"
  • "And, at that rate, you're better off just utilizing the Enum class." -> "而且,在这种情况下,最好直接使用 Enum 类。"
  • "Here is a tutorial on Java reflection with enums, for this specific requirement." -> "这里有一个关于在特定需求下使用 enums 的Java反射教程。"
  • "Examining Enums (The Java&trade; Tutorials &gt; The Reflection API &gt; Arrays and Enumerated Types)" -> "查看Enums (Java&trade;教程 &gt; 反射API &gt; 数组和枚举类型)"
  • "Since you know that your map values are going to be enum objects, you can utilize the Enum#valueOf method, to obtain a single value." -> "由于你知道你的映射值将是 enum 对象,你可以利用 Enum#valueOf 方法来获取单个值。"
  • "If you want a list of values, similar to the values method, you can use an array of Enum and utilize the Class#getEnumConstants." -> "如果你想要一个类似于 values 方法的值列表,你可以使用 Enum 数组并利用 Class#getEnumConstants。"
  • "java\nMap&lt;String, Class&lt;? extends Enum&gt;&gt; map = new HashMap&lt;&gt;();\nmap.put(&quot;Animal&quot;, Animal.class);\nmap.put(&quot;Bird&quot;, Bird.class);\nfor (Enum value : map.get(&quot;Animal&quot;).getEnumConstants()) \n System.out.println(value.name());\n" -> "java\nMap&lt;String, Class&lt;? extends Enum&gt;&gt; map = new HashMap&lt;&gt;();\nmap.put(&quot;Animal&quot;, Animal.class);\nmap.put(&quot;Bird&quot;, Bird.class);\nfor (Enum value : map.get(&quot;Animal&quot;).getEnumConstants()) \n System.out.println(value.name());\n"
英文:

There doesn't appear to be an exact solution to what you're looking to achieve.

Essentially, I believe that since an enum is considered a static object, you cannot cast the static reference into a new object.

You would have to use a Class&lt;Animal&gt; type.
And, at that rate, you're better off just utilizing the Enum class.

Here is a tutorial on Java reflection with enums, for this specific requirement.
Examining Enums (The Java&trade; Tutorials &gt; The Reflection API &gt; Arrays and Enumerated Types).

Since you know that your map values are going to be enum objects, you can utilize the Enum#valueOf method, to obtain a single value.

If you want a list of values, similar to the values method, you can use an array of Enum and utilize the Class#getEnumConstants.

Map&lt;String, Class&lt;? extends Enum&gt;&gt; map = new HashMap&lt;&gt;();
map.put(&quot;Animal&quot;, Animal.class);
map.put(&quot;Bird&quot;, Bird.class);
for (Enum value : map.get(&quot;Animal&quot;).getEnumConstants()) 
    System.out.println(value.name());

答案4

得分: -1

我通过Reflections找到了一个解决方案。可以这样做:

Map<String, Class<? extends Enum<?>>> errorCodes = errorCodeMap.getErrorCodeMap();
Class<? extends Enum<?>> enumClass = errorCodes.get(code.substring(0, 1));
Enum<?>[] enumConstants = enumClass.getEnumConstants();
Class<?> actualEnumClass = enumConstants[0].getDeclaringClass();
StringBuilder errorCode = new StringBuilder().append(prefix).append(code);
Enum<?> errorEnum = Enum.valueOf(actualEnumClass.asSubclass(Enum.class), errorCode.toString());
英文:

I found a solution through Reflections . It can be sone like this

Map&lt;String, Class&lt;? extends Enum&lt;?&gt;&gt;&gt; errorCodes = errorCodeMap.getErrorCodeMap();
Class&lt;? extends Enum&lt;?&gt;&gt; enumClass = errorCodes.get(code.substring(0, 1));
Enum&lt;?&gt;[] enumConstants = enumClass.getEnumConstants();
Class&lt;?&gt; actualEnumClass = enumConstants[0].getDeclaringClass();
StringBuilder errorCode = new StringBuilder().append(prefix).append(code);
Enum&lt;?&gt; errorEnum = Enum.valueOf(actualEnumClass.asSubclass(Enum.class), errorCode.toString());

huangapple
  • 本文由 发表于 2023年5月31日 23:52:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375315.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定