Вопрос-ответ

How can I initialise a static Map?

Как я могу инициализировать статическую карту?

Как бы вы инициализировали статическую карту Map в Java?

Метод первый: статический инициализатор
Метод второй: инициализатор экземпляра (анонимный подкласс) или какой-либо другой метод?

Каковы плюсы и минусы каждого из них?

Вот пример, иллюстрирующий два метода:

import java.util.HashMap;
import java.util.Map;

public class Test {
private static final Map<Integer, String> myMap = new HashMap<>();
static {
myMap.put(1, "one");
myMap.put(2, "two");
}

private static final Map<Integer, String> myMap2 = new HashMap<>(){
{
put(1, "one");
put(2, "two");
}
};
}
Переведено автоматически
Ответ 1

В данном случае инициализатор экземпляра - это просто синтаксический сахар, верно? Я не понимаю, зачем вам нужен дополнительный анонимный класс только для инициализации. И это не сработает, если создаваемый класс является окончательным.

Вы также можете создать неизменяемую карту, используя статический инициализатор:

public class Test {
private static final Map<Integer, String> myMap;
static {
Map<Integer, String> aMap = ....;
aMap.put(1, "one");
aMap.put(2, "two");
myMap = Collections.unmodifiableMap(aMap);
}
}
Ответ 2

Мне нравится способ Guava инициализации статической неизменяемой карты:

static final Map<Integer, String> MY_MAP = ImmutableMap.of(
1, "one",
2, "two"
);

Как вы можете видеть, она очень лаконична (из-за удобных заводских методов в ImmutableMap).

Если вы хотите, чтобы на карте было более 5 записей, вы больше не можете использовать ImmutableMap.of(). Вместо этого попробуйте ImmutableMap.builder() в следующих строках:

static final Map<Integer, String> MY_MAP = ImmutableMap.<Integer, String>builder()
.put(1, "one")
.put(2, "two")
// ...
.put(15, "fifteen")
.build();

Чтобы узнать больше о преимуществах утилит неизменяемых коллекций Guava, см. Описание неизменяемых коллекций в Руководстве пользователя Guava.

Раньше Guava (подмножество) называлась Google Collections. Если вы еще не используете эту библиотеку в своем Java-проекте, я настоятельно рекомендую попробовать ее! Guava быстро стала одной из самых популярных и полезных бесплатных сторонних библиотек для Java, с чем согласны другие пользователи SO. (Если вы новичок в этом, по этой ссылке есть несколько отличных учебных ресурсов.)


Обновление (2015): Что касается Java 8, я бы все равно использовал подход Guava, потому что он намного чище всего остального. Если вам не нужна зависимость от Guava, рассмотрите простой старый метод инициализации. Взлом с двумерным массивом и потоковым API довольно уродлив, если вы спросите меня, и становится еще уродливее, если вам нужно создать карту, ключи и значения которой не одного типа (как Map<Integer, String> в вопросе).

Что касается будущего Guava в целом, что касается Java 8, Луи Вассерман сказал об этом еще в 2014 году, а [обновление] в 2016 году было объявлено, что Guava 21 будет требовать и должным образом поддерживать Java 8.


Обновление (2016): как указывает Тагир Валеев, Java 9 наконец-то сделает это простым, используя только чистый JDK, добавив удобные фабричные методы для коллекций:

static final Map<Integer, String> MY_MAP = Map.of(
1, "one",
2, "two"
);
Ответ 3

Я бы использовал:

public class Test {
private static final Map<Integer, String> MY_MAP = createMap();

private static Map<Integer, String> createMap() {
Map<Integer, String> result = new HashMap<>();
result.put(1, "one");
result.put(2, "two");
return Collections.unmodifiableMap(result);
}
}

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

  2. это делает создание карты более явным

  3. это делает карту неизменяемой

  4. поскольку MY_MAP является константой, я бы назвал ее как constant

Ответ 4

Java 5 предоставляет этот более компактный синтаксис:

static final Map<String , String> FLAVORS = new HashMap<String , String>() {{
put("Up", "Down");
put("Charm", "Strange");
put("Top", "Bottom");
}};
java collections