adding multiple entries to a HashMap at once in on

2019-01-29 20:26发布

I need to initialize a constant HashMap and would like to do it in one line statement. Avoiding sth like this:

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

similar to this in objective C:

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

I have not found any example that shows how to do this having looked at so many.

9条回答
淡お忘
2楼-- · 2019-01-29 21:04

Another approach may be writing special function to extract all elements values from one string by regular-expression:

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;
    }
}
查看更多
再贱就再见
3楼-- · 2019-01-29 21:08
    boolean x;
    for (x = false, 
        map.put("One", new Integer(1)), 
        map.put("Two", new Integer(2)),      
        map.put("Three", new Integer(3)); x;);

Ignoring the declaration of x (which is necessary to avoid an "unreachable statement" diagnostic), technically it's only one statement.

查看更多
淡お忘
4楼-- · 2019-01-29 21:09

Maps have also had factory methods added in Java 9. For up to 10 entries Maps have overloaded constructors that take pairs of keys and values. For example we could build a map of various cities and their populations (according to google in October 2016) as follow:

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

The var-args case for Map is a little bit harder, you need to have both keys and values, but in Java, methods can’t have two var-args parameters. So the general case is handled by taking a var-args method of Map.Entry<K, V> objects and adding a static entry() method that constructs them. For example:

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

Collection Factory Methods in Java 9

查看更多
Juvenile、少年°
5楼-- · 2019-01-29 21:12

You could add this utility function to a utility class:

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");

Note: in Java 9 you can use Map.of

查看更多
Ridiculous、
6楼-- · 2019-01-29 21:13

You can use Google Guava's ImmutableMap. This works as long as you don't care about modifying the Map later (you can't call .put() on the map after constructing it using this method):

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();

See also: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html

A somewhat related question: ImmutableMap.of() workaround for HashMap in Maps?

查看更多
劳资没心,怎么记你
7楼-- · 2019-01-29 21:16

You can do this:

Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};
查看更多
登录 后发表回答