it-roy-ru.com

добавление нескольких записей в HashMap одновременно в одном операторе

Мне нужно инициализировать константу 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] 

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

104
user387184

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

Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};
205
Eng.Fouad

Вы можете использовать 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 в Картах?

54
JimmyT

Начиная с 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 ), чтобы добавить эту функцию для вас.

33
Timo Türschmann

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

Если вам нужен синтаксис такого типа, рассмотрите некоторые Groovy, которые совместимы с Java и позволяют вам:

def map = [name:"Gromit", likes:"cheese", id:1234]
8
dfraser

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

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}

6
Dakusan

К картам также добавлены фабричные методы в 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

5
Sadiq Ali
    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 (которое необходимо, чтобы избежать диагностики «недостижимый оператор»), технически это всего лишь один оператор.

5
Hot Licks

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

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

1
R. Oosterholt

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

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;
    }
}
0
Uri Ziv