Как создать статическую карту String → Array

Мне нужно создать статический Map, который отображает данный String в массив int.

Другими словами, я хотел бы определить что-то вроде:

"fred" -> {1,2,5,8}
"dave" -> {5,6,8,10,11}
"bart" -> {7,22,10010}
... etc

Есть ли простой способ сделать это в Java?

И если возможно, я бы хотел использовать константы static для значений String и int.

РЕДАКТИРОВАТЬ: Чтобы уточнить, что я имел в виду под константами static для значений, и дать то, что я считаю правильным кодом, вот мой первый удар по решению:

public final static String FRED_TEXT = "fred";
public final static String DAVE_TEXT = "dave";

public final static int ONE = 1;
public final static int TWO = 2;
public final static int THREE = 3;
public final static int FOUR = 4;

public final static HashMap<String, int[]> myMap = new HashMap<String, int[]>();
static {
    myMap.put(FRED_TEXT, new int[] {ONE, TWO, FOUR});
    myMap.put(DAVE_TEXT, new int[] {TWO, THREE});
}

Обратите внимание: эти имена не то, что я на самом деле использую. Это просто надуманный пример.

Ответ 1

Вам не нужно разделять объявление и инициализацию. Если вы знаете, как все это можно сделать в одной строке!

// assumes your code declaring the constants ONE, FRED_TEXT etc is before this line
private static final Map<String, int[]> myMap = Collections.unmodifiableMap(
    new HashMap<String, int[]>() {{
        put(FRED_TEXT, new int[] {ONE, TWO, FOUR});
        put(DAVE_TEXT, new int[] {TWO, THREE});
    }});

Здесь у нас анонимный класс с блоком инициализации - блок кода, который выполняется при построении после конструктора, который мы имеем используемый здесь для загрузки карты (это иногда ошибочно называют "инициализацией двойной скобки" - я полагаю, потому что есть две соседние фигурные скобки =, но на самом деле нет такой вещи).

Две интересные вещи об этом: a) он женится на объявлении с содержимым и b), поскольку инициализация находится в строке, вы также можете сделать оперативный вызов Collections.unmodifiableMap(), что приведет к аккуратной односторонней настройке, объявление строки, инициализация и преобразование в немодифицируемую.

Если вам не нужно/хотите, чтобы карта была немодифицируемой, оставьте этот вызов:

private static final Map<String, int[]> myMap = new HashMap<String, int[]>() {{
    put(FRED_TEXT, new int[] {ONE, TWO, FOUR});
    put(DAVE_TEXT, new int[] {TWO, THREE});
}};

Ответ 2

Вам нужно объявить и инициализировать свою статическую карту отдельно.

Вот фрагмент объявления:

private static final Map<String,int[]> MyMap;

Вот фрагмент инициализации:

static {
    Map<String,int[]> tmpMap = new HashMap<String,int[]>();
    tmpMap.put("fred", new int[] {1,2,5,8});
    tmpMap.put("dave", new int[] {5,6,8,10,11});
    tmpMap.put("bart", new int[] {7,22,10010});
    MyMap = Collections.unmodifiableMap(tmpMap);
}

К сожалению, массивы всегда доступны для записи на Java. Вы не сможете назначить MyMap, но вы сможете добавлять или удалять значения из других частей вашей программы, которые обращаются к карте.

Ответ 3

Для полноты, так как это первый результат в google для 'java static define map' В Java 8 вы можете это сделать.

Collections.unmodifiableMap(Stream.of(
            new SimpleEntry<>("a", new int[]{1,2,3}),
            new SimpleEntry<>("b", new int[]{1,2,3}),
            new SimpleEntry<>("c", new int[]{1,2,3}))
            .collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())));

Эта приятная часть с этим заключается в том, что мы больше не создаем анонимные классы с синтаксисом двойной привязки ({{ }})

Затем мы можем расширить это с помощью некоторого кода, чтобы очистить шаблон, как этот парень сделал здесь http://minborgsjavapot.blogspot.ca/2014/12/java-8-initializing-maps-in-smartest-way.html

public static <K, V> Map.Entry<K, V> entry(K key, V value) {
    return new AbstractMap.SimpleEntry<>(key, value);
}

public static <K, U> Collector<Map.Entry<K, U>, ?, Map<K, U>> entriesToMap() {
    return Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue());
}

public static <K, U> Collector<Map.Entry<K, U>, ?, ConcurrentMap<K, U>> entriesToConcurrentMap() {
    return Collectors.toConcurrentMap((e) -> e.getKey(), (e) -> e.getValue());
}

конечный результат

Collections.unmodifiableMap(Stream.of(
            entry("a", new int[]{1,2,3}),
            entry("b", new int[]{1,2,3}),
            entry("c", new int[]{1,2,3}))
            .collect(entriesToMap()));

что дало бы нам одновременную немодифицируемую карту.

Ответ 4

static Map<String, int[]> map = new HashMap<>();

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

Ответ 5

public class ExampleClass {
    public final static HashMap consts = new HashMap();
    static
    {
        constants.put("A", "The Letter A");
        constants.put("B", "The Letter B");
        constants.put("C", "The Letter C");
    }
    /* Rest of your class that needs to know the consts */
}