Java HashMap-это необходимо использовать.put () для каждого набора? [дубликат]
этот вопрос уже есть ответ здесь:
представьте себе следующую ситуацию. У вас есть набор значений, которые уже доступны и известны. Вы должны поместить их в HashMap по причинам.
код пример:
String a = "a";
Strinb b = "b";
...
HashMap map = new HashMap(5);
map.put("a", a);
map.put("b", b);
...
это действительно необходимо, чтобы сделать это так? Я не могу поверить, что нет конструктора, который позволил бы вам поместить ваши значения с нуля.
Я говорю о чем-то вроде этого:
HashMap map = new HashMap(<"a", a>, <"b", b>, ...);
или даже что-то вроде этого:
HashMap map = new HashMap(5);
HashMap.putBunchOfStuff("a", a, "b", b, ...);
редактировать: я собирался спросить, если есть способ но главное, если ответ "Нет", почему нет такого конструктора/метода.
4 ответов
к сожалению, коллекция литералы были предложение по проекту Coin в Java 7 (и Java 8), но он никогда не попадал в конечный продукт, он же не является особенностью Java.
предложение было такое
Here’s how it would look with map literals:
final Map<Integer, String> platonicSolids = {
4 : "tetrahedron",
6 : "cube",
8 : "octahedron",
12 : "dodecahedron",
20 : "icosahedron"
};
Here is the empty map literal, which has a slightly irregular syntax to make
it differ from the empty set:
Map<String, Integer> noJokeHere = { : };
но этого никогда не было, так что, к сожалению, это не работает. Так что, если вы не напишете свой собственный волшебный строитель или фантазии лямбда, как на этом сайте Per-Åke Minborg, ты на твой собственный. Однако следующее с сайта должно работать (в Java 8).
//copy paste from linked site
Map<Integer, String> map = Stream.of(
new SimpleEntry<>(0, "zero"),
new SimpleEntry<>(1, "one"),
//...
new SimpleEntry<>(11, "eleven"),
new SimpleEntry<>(12, "twelve"))
.collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue()));
и упрощенная версия, также из сайт:
//copy paste from linked site
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());
}
Map<Integer, String> map = Stream.of(
entry(0, "zero"),
//...
entry(12, "twelve"))
.collect(entriesToMap());
литералы коллекции не были введены из-за эти пункты:
"простая" версия этой функции (только наборы, списки, карты) не является очень удовлетворительный или популярный; "расширяемая" версия этой функции открытый, грязный и практически гарантированный путь overrun свой дизайн бюджет;
версия на основе библиотеки дает нам X% преимущества для 1% стоимость, где X >> 1;
типы значений приходят, и "как будет выглядеть эта функция" в мире с ценностными типами вполне может быть совсем иначе, чем в мире без, предполагая, что было бы сомнительно попробовать и сделать эту работу перед типами значений;
мы лучше фокусируем наше ширина полосы частот язык-дизайна дальше решение более фундаментальных проблем, лежащих в основе библиотечного дела версия (включая: более эффективные varargs, константы массива в постоянный пул, неизменяемые массивы и поддержка кэширования (и восстановления под давлением) промежуточные неизменяемые результаты).
по умолчанию нет такого конструктора - вы можете использовать идиому двойной скобки для put
все значения в карте при создании экземпляра, но для этого все еще требуется несколько вызовов put:
Map<String,String> map = new HashMap<>() {{
put("a", "val1");
put("b", "val2");
//etc.
}};
на самом деле у вас обычно есть большие блоки данных, которые вы хотите поместить в карту, доступную из потока или другой коллекции, поэтому тривиально перебирать несколько put
звонки в этом случае.
у гуавы есть putAll()
на ImmutableMap.Builder
, позволяя вам сделать что - то подобное к этому до создания экземпляра. Другие внешние библиотеки могут иметь другое подобное поведение, но на самом деле вам придется прибегать к использованию внешних библиотек.
можно создать довольно полезный метод для создания карт с помощью varargs.
пример:
@SuppressWarnings("unchecked")
public static <K, V> HashMap<K, V> newMap(Object... elems) {
HashMap<K, V> m = new HashMap<K, V>();
for (int i = 0; i < elems.length; i += 2) {
m.put((K) elems[i], (V) elems[i + 1]);
}
return m;
}
Map<String, Integer> m = newMap("k1", 1, "k2", 2);
внимание: это не тип safe и может привести к карте с объектами неправильных типов, если вы сделаете ошибку при ее использовании, бросая ClassCastException
в неожиданных местах. Это называется загрязнение "кучи". Пример:
Map<String, Integer> m = newMap("k1", 1, "k2", "2");
int s = m.get("k2"); // ClassCastException!
вы можете использовать что-то вроде этого :
HashMap<String, String> map = new HashMap<String, String>(5){{
put("a", "a");
put("b", "b");
}};
но я не знаю, можно ли использовать u с локальной переменной a и b.