Как поместить строковые элементы в карту перечислений перечислений String? - PullRequest
0 голосов
/ 30 мая 2011

Я хотел бы создать массив (enum) массива (enum) массива (enum) строк. Я не думаю, что это возможно сделать в 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?


    }
}

Приведенный выше код компилируется, но как я могу поместить и получить строковые элементы в моей карте?

Ответы [ 5 ]

2 голосов
/ 30 мая 2011

Разве это не должно быть 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 напрямую, чтобы сделать его немного более управляемым.

Если вы используете все позиции в массивах, вы можете использовать порядковое значение перечисления каквместо этого индекс в обычный массив.

1 голос
/ 30 мая 2011

Вы можете найти это полезным:

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;
}
1 голос
/ 30 мая 2011

открытый класс 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});
}

}

Это довольно уродливый код.Чтобы очистить его (и обеспечить некоторую безопасность типов), вы можете определить свой собственный класс для хранения тройки перечислений, по одному от каждого из ваших типов перечислений, и определить его методы hashcode и equals.Вы также можете найти способ Arrays.hashcode(Object[]) полезным.

0 голосов
/ 30 мая 2011

Хорошо, вот решение, основанное на предложении @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 голосов
/ 30 мая 2011

Я не думаю, что вы поняли концепцию перечислений в 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 требует, чтобы тип (перечисления, используемого в качестве ключей) передавался в качестве аргумента. Затем его можно использовать как любую другую карту со стандартной семантикой put и get.

...