2011-05-30 171 views
0

我想创建一个数组(枚举)数组(枚举)的数组(枚举)的字符串的数组(枚举)。我不认为用Java实现这一点是可能的,但我听说过EnumMap。如何将字符串项目放在一个枚举枚举的枚举映射的字符串?

public class Tricky { 

    public enum enumA { A1, A2, A3 }; 
    public enum enumB { B1, B2, B3 }; 
    public enum enumC { C1, C2, C3 }; 

    HashMap<EnumMap<enumA, EnumMap<enumB, enumC>>,String> item 
     = new HashMap<EnumMap<enumA, EnumMap<enumB, enumC>>,String>(); 

    public Tricky() { 

     // How do I put and get strings in my hash map? 


    } 
} 

上面的代码可以编译,但是我怎样才能在我的地图中放置并获取字符串项呢?

+0

你可以有希望做到这一点可能是什么原因? EnumMap只是一个非常快速,高效的Map实现,当Enums是关键字时,其他值就是值。 – I82Much 2011-05-30 00:48:07

+0

您是否试图将'enumA','enumB'和'enumC'中的一个值映射到一个字符串? – 2011-05-30 00:51:44

+0

@Ted Hopp是的,想法是我想通过提供enumA,enumB和enumC来检索我的字符串。 – JVerstry 2011-05-30 00:54:13

回答

1

你可能会发现这个有用:

package p; 
enum enumA { 
    A1,A2,A3; 
} 
enum enumB { 
    B1,B2,B3; 
} 
enum enumC { 
    C1,C2,C3; 
} 
class MyArray{ 
    MyArray(Class<? extends Enum> e1,Class<? extends Enum> e2,Class<? extends Enum> e3) { 
     strings=new String[e1.getEnumConstants().length][e1.getEnumConstants().length][e2.getEnumConstants().length]; 
     e3.getEnumConstants(); 
    } 
    void set(enumA a,enumB b,enumC c,String string) { 
     strings[a.ordinal()][b.ordinal()][c.ordinal()]=string; 
    } 
    String get(enumA a,enumB b,enumC c) { 
     return strings[a.ordinal()][b.ordinal()][c.ordinal()]; 
    } 
    public String toString() { 
     StringBuffer sb=new StringBuffer(); 
     for(enumA a:enumA.values()) 
      for(enumB b:enumB.values()) { 
       for(enumC c:enumC.values()) { 
        sb.append(get(a,b,c)); 
        sb.append('\n'); 
       } 
       sb.append('\n'); 
      } 
     return sb.toString(); 
    } 
    public static void main(String[] arguments) { 
     MyArray myArray=new MyArray(enumA.class,enumB.class,enumC.class); 
     for(enumA a:enumA.values()) 
      for(enumB b:enumB.values()) 
       for(enumC c:enumC.values()) 
        myArray.set(a,b,c,""+a+b+c); 
     System.out.println(myArray); 
    } 
    final String[][][] strings; 
} 
+0

确实是一种非常有趣的方法。结构的初始化更简单... – JVerstry 2011-05-30 03:59:14

-1

我不认为你已经理解了Java中的枚举概念;它就像任何其他类型一样。如果您必须将其视为一个类,则对于Java中的所有枚举,扩展为java.lang.Enum。因此,你可以组成枚举数组(或至少它们的值/常量,如果你这是你的意思)。看看下面的例子:

package com.example; 

public class Enumerations { 

    public enum enumA { A1, A2, A3 }; 
    public enum enumB { B1, B2, B3 }; 
    public enum enumC { C1, C2, C3 }; 

    private void test() { 
     Enumerations.enumA[] enumerations = new Enumerations.enumA[3]; 
     enumerations[0] = enumA.A1; 
     enumerations[1] = enumA.A2; 
     enumerations[2] = enumA.A3; 
    } 
} 

你不能在阵列中混合与其他类型的枚举,如果这是你的意思。换句话说,您不能创建具有不同类型的多维数组:数组的类型与声明中指定的类型相同;这样声明包含枚举的数组不能包含字符串,即使它是多维的。因此,下面的片段是非法的:

package com.example; 

public class Enumerations { 

    public enum enumA { A1, A2, A3 }; 
    public enum enumB { B1, B2, B3 }; 
    public enum enumC { C1, C2, C3 }; 

    private void test() { 
     Enumerations.enumA[][] enumerations = new Enumerations.enumA[3][]; 
     enumerations[0][1] = enumA.A1; //legal 
     enumerations[0][2] = enumB.B1; //illegal since enumB is a different type 
    } 

至于你原来的问题而言,使用EnumMap的密钥是枚举通过以下方式进行:

private void createAndStoreEnum() { 
     EnumMap<Enumerations.enumA, String> aMap = new EnumMap<Enumerations.enumA, String>(enumA.class); 
     aMap.put(enumA.A1, "Example"); 
} 

的EnumMap的构造函数中使用,要求(用作键的枚举的类型)作为参数传入。然后可以像其他任何地图一样使用它,并使用标准的语义和语义。

+0

我想要实现的是访问字符串的枚举类型或数组等。这不是1级枚举。它是一个多级枚举。可能这是不可能的... – JVerstry 2011-05-30 00:57:43

+0

@JVerstry,我想我已经在一定程度上理解了你的问题。我编辑了我的答案,以证明为什么数组在这里不起作用。我认为你需要使用enumMap。希望这个片段能让你开始。 – 2011-05-30 01:04:42

+0

@JVerstry,我看着你的代码在这个问题上。你如何试图将多级枚举映射到字符串?我认为使用包含EnumMaps的HashMap会是错误方向上的一步。 – 2011-05-30 01:11:10

2

不应该是EnumMap<EnumA, EnumMap<EnumB, EnumMap<EnumC, String>>>?在这种情况下,你会做

EnumMap<...> enumMapC = new EnumMap<...>(); 
enumMapC.put(EnumC.VALUE, "SomeString"); 
EnumMap<...> enumMapB = new EnumMap<...>(); 
enumMapB.put(EnumB.VALUE, enumMapC); 
EnumMap<...> enumMapA = new EnumMap<...>(); 
enumMapA.put(EnumA.VALUE, enumMapB); 

虽然我会建议你使用一个好的IDE来编码。你可能想考虑创建一些类,而不是直接使用EnumMap来使它更易于管理。

如果您使用数组中的所有位置,则可能需要使用枚举的序号值作为正常数组中的索引。

+0

你可能是对的,我正在测试一些东西... – JVerstry 2011-05-30 01:07:24

1

公共类整蛊{

public enum enumA { A1, A2, A3 }; 
public enum enumB { B1, B2, B3 }; 
public enum enumC { C1, C2, C3 }; 

HashMap<Object[],String> item = new HashMap<Object[],String>(); 

public Tricky() { 
    item.put(new Object[] {enumA.A1, enumB.B2, enumC.C3}, "A1_B2_C3 string"); 
    String oops = item.get(new Object[] {enumA.A2, enumB.B3, enumC.C1}); 
} 

}

这是相当丑陋的代码。为了清理它(并提供某种类型的安全性),您可以定义自己的类来保存枚举的三元组,每个枚举类型都有一个,并定义它的方法hashcodeequals。您也可以找到有用的方法Arrays.hashcode(Object[])

+0

这是一个肯定的想法...谢谢! – JVerstry 2011-05-30 01:09:13

0

好的,这里是基于@owlstead提出的建议的解决方案。它的工作原理:

public class Tricky { 

    public enum enumA { A1, A2, A3 }; 
    public enum enumB { B1, B2, B3 }; 
    public enum enumC { C1, C2, C3 }; 

    static EnumMap<enumA,EnumMap<enumB,EnumMap<enumC,String>>> items; 

    public static void main(String[] args) { 

     // Creating my array (enum) of array (enum) of array (enum) of strings 
     items = new EnumMap<enumA, 
         EnumMap<enumB, 
          EnumMap<enumC,String>>>(
           enumA.class); 

     // We need to add entries 
     for (enumA itemA : enumA.values()) { 

      EnumMap<enumB, 
       EnumMap<enumC,String>> itemsB = 
        new EnumMap<enumB, 
         EnumMap<enumC,String>>(enumB.class); 

      // And sub-entries... 
      for (enumB itemB : enumB.values()) 
       itemsB.put(itemB, new EnumMap<enumC,String>(enumC.class)); 

      items.put(itemA, itemsB); 

     } 

     // Putting a value 
     items.get(enumA.A2).get(enumB.B3).put(enumC.C1, "MyValue"); 

     // Retrieving a value 
     String retr = items.get(enumA.A2).get(enumB.B3).get(enumC.C1); 
     String retr2 = items.get(enumA.A3).get(enumB.B3).get(enumC.C2); 

     System.out.println(retr); 
     System.out.println(retr2); 

    } 

} 
+0

当我醒来时,我正在考虑这个问题,我想你可能想创建一个不可变的类来保存字段中所有三个枚举的值,编写一个好的equals()和hash()方法,然后使用该类作为HashMap 中的键。但这只是一个暗示,而不是对你的问题的直接回答。 – 2011-05-30 15:22:16

+0

@owlstead你提出的建议确实是一个解决方案,但是它引发了一个额外的课程。我终于实现了类似Ray的提议。对于相同的功能它更简单。谢谢。 – JVerstry 2011-05-30 20:28:22