добавление нескольких записей в HashMap одновременно в одном операторе - PullRequest
115 голосов
/ 24 ноября 2011

Мне нужно инициализировать константу HashMap и я хотел бы сделать это в одной строковой инструкции.Как избежать этого:

  hashMap.put("One", new Integer(1)); // adding value into HashMap
  hashMap.put("Two", new Integer(2));      
  hashMap.put("Three", new Integer(3));

похоже на это в задаче C:

[NSDictionary dictionaryWithObjectsAndKeys:
@"w",[NSNumber numberWithInt:1],
@"K",[NSNumber numberWithInt:2],
@"e",[NSNumber numberWithInt:4],
@"z",[NSNumber numberWithInt:5],
@"l",[NSNumber numberWithInt:6],
nil] 

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

Ответы [ 9 ]

223 голосов
/ 24 ноября 2011

Вы можете сделать это:

Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};
55 голосов
/ 15 мая 2014

Вы можете использовать Google Guava ImmutableMap. Это работает до тех пор, пока вам не нужно изменять карту позже (вы не можете вызвать .put () на карте после ее построения с помощью этого метода):

import com.google.common.collect.ImmutableMap;

// For up to five entries, use .of()
Map<String, Integer> littleMap = ImmutableMap.of(
    "One", Integer.valueOf(1),
    "Two", Integer.valueOf(2),
    "Three", Integer.valueOf(3)
);

// For more than five entries, use .builder()
Map<String, Integer> bigMap = ImmutableMap.<String, Integer>builder()
    .put("One", Integer.valueOf(1))
    .put("Two", Integer.valueOf(2))
    .put("Three", Integer.valueOf(3))
    .put("Four", Integer.valueOf(4))
    .put("Five", Integer.valueOf(5))
    .put("Six", Integer.valueOf(6))
    .build();

См. Также: http://docs.guava -libraries.googlecode.com / git / javadoc / com / google / common / collect / ImmutableMap.html

Несколько связанный вопрос: Обходной путь ImmutableMap.of () для HashMap в Картах?

38 голосов
/ 26 апреля 2016

Начиная с Java 9, можно использовать Map.of(...), например:

Map<String, Integer> immutableMap = Map.of("One", 1, 
                                           "Two", 2, 
                                           "Three", 3);

Эта карта является неизменной.Если вы хотите, чтобы карта была изменчивой, вы должны добавить:

Map<String, Integer> hashMap = new HashMap<>(immutableMap);

Если вы не можете использовать Java 9, вы застряли в написании подобного вспомогательного метода самостоятельно или в сторонней библиотеке(например, Guava ), чтобы добавить эту функцию для вас.

8 голосов
/ 24 ноября 2011

Java не имеет литерала карты, поэтому нет хорошего способа сделать именно то, что вы запрашиваете.

Если вам нужен этот тип синтаксиса, рассмотрите некоторый Groovy, который совместим с Java и позволяет вам делать:

def map = [name:"Gromit", likes:"cheese", id:1234]
7 голосов
/ 21 сентября 2017

К картам также добавлены фабричные методы в Java 9. До 10 записей Карты имеют перегруженные конструкторы, которые принимают пары ключей и значений.Например, мы могли бы построить карту различных городов и их населения (по данным Google в октябре 2016 года) следующим образом:

Map<String, Integer> cities = Map.of("Brussels", 1_139000, "Cardiff", 341_000);

Вариант var-args для Map немного сложнее, вам нужно иметьи ключи и значения, но в Java методы не могут иметь два параметра var-args.Таким образом, общий случай обрабатывается путем использования метода var-args для объектов Map.Entry<K, V> и добавления статического метода entry(), который их создает.Например:

Map<String, Integer> cities = Map.ofEntries(
    entry("Brussels", 1139000), 
    entry("Cardiff", 341000)
);

Методы фабрики сбора в Java 9

6 голосов
/ 16 мая 2015

Вот простой класс, который выполнит то, что вы хотите

import java.util.HashMap;

public class QuickHash extends HashMap<String,String> {
    public QuickHash(String...KeyValuePairs) {
        super(KeyValuePairs.length/2);
        for(int i=0;i<KeyValuePairs.length;i+=2)
            put(KeyValuePairs[i], KeyValuePairs[i+1]);
    }
}

А затем использовать его

Map<String, String> Foo=QuickHash(
    "a", "1",
    "b", "2"
);

Это дает {a:1, b:2}

3 голосов
/ 24 ноября 2011
    boolean x;
    for (x = false, 
        map.put("One", new Integer(1)), 
        map.put("Two", new Integer(2)),      
        map.put("Three", new Integer(3)); x;);

Игнорирование объявления x (которое необходимо, чтобы избежать диагностики «недостижимый оператор»), технически это только один оператор.

1 голос
/ 23 мая 2017

Вы можете добавить эту функцию утилиты к классу утилит:

public static <K, V> Map<K, V> mapOf(Object... keyValues) {
    Map<K, V> map = new HashMap<>();

    for (int index = 0; index < keyValues.length / 2; index++) {
        map.put((K)keyValues[index * 2], (V)keyValues[index * 2 + 1]);
    }

    return map;
}

Map<Integer, String> map1 = YourClass.mapOf(1, "value1", 2, "value2");
Map<String, String> map2 = YourClass.mapOf("key1", "value1", "key2", "value2");

Примечание: в Java 9 вы можете использовать Map.of

0 голосов
/ 09 сентября 2015

Другим подходом может быть написание специальной функции для извлечения всех значений элементов из одной строки с помощью регулярного выражения:

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {
    public static void main (String[] args){
        HashMap<String,Integer> hashMapStringInteger = createHashMapStringIntegerInOneStat("'one' => '1', 'two' => '2' , 'three'=>'3'  ");

        System.out.println(hashMapStringInteger); // {one=1, two=2, three=3}
    }

    private static HashMap<String, Integer> createHashMapStringIntegerInOneStat(String str) {
        HashMap<String, Integer> returnVar = new HashMap<String, Integer>();

        String currentStr = str;
        Pattern pattern1 = Pattern.compile("^\\s*'([^']*)'\\s*=\\s*>\\s*'([^']*)'\\s*,?\\s*(.*)$");

        // Parse all elements in the given string.
        boolean thereIsMore = true;
        while (thereIsMore){
            Matcher matcher = pattern1.matcher(currentStr);
            if (matcher.find()) {
                returnVar.put(matcher.group(1),Integer.valueOf(matcher.group(2)));
                currentStr = matcher.group(3);
            }
            else{
                thereIsMore = false;
            }
        }

        // Validate that all elements in the given string were parsed properly
        if (currentStr.length() > 0){
            System.out.println("WARNING: Problematic string format. given String: " + str);
        }

        return returnVar;
    }
}
...