开发者

How to put string items in a map of enums of enums of enums of String?

I would like to create an array (enum) of array (enum) of array (enum) of Strings. I don't think it is possible to achieve this in Java, but I have heard about 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?


    }
}

The above code compiles, but how can I put and get string items in my map?


Shouldn't that be EnumMap<EnumA, EnumMap<EnumB, EnumMap<EnumC, String>>> ? In that case you would do

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);

Although I would advise you to use a good IDE to code this. And you might want to consider to create some classes instead of using EnumMap directly to make it a bit more manageable.

If you use all positions in the arrays, you might want to use the ordinal value of the enum as an index into a normal array instead.


you might find this useful:

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;
}


public class Tricky {

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});
}

}

That's pretty ugly code. To clean it up (and provide some type safety), you could define your own class for holding a triplet of enums, one from each of your enum types, and define its hashcode and equals methods. You may also find the method Arrays.hashcode(Object[]) useful.


Ok, here is the solution based on the suggestion made by @owlstead. It works:

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);

    }

}


I do not think you've understood the concept of enumerations in Java; it is just like any other type. Consider it as a class if you must, for all enums in Java extend java.lang.Enum. You can therefore compose arrays of enums (or atleast their values/constants, if you that is what you meant). Take a look at the following example:

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;
    }
}

You cannot mix enums with other types in the array, if that is what you meant. In other words, you cannot create a multi-dimensonal array with different types: the type of the array is the same as the one specified in the declaration; that way an array declared to contain enums cannot contain strings, even if it is multi-dimensional. The following snippet therefore is illegal:

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
    }

As far as your original question is concerned, using the EnumMap where the keys are enums is done in the following manner:

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

The EnumMap constructor used, requires the type (of the enum used as keys) to be passed in as the argument. It can then be used like any other map, with the standard put and get semantics.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜