adding multiple entries to a HashMap at once in one statement

186,041

Solution 1

You can use the Double Brace Initialization as shown below:

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

As a piece of warning, please refer to the thread Efficiency of Java “Double Brace Initialization" for the performance implications that it might have.

Solution 2

Since Java 9, it is possible to use Map.of(...), like so:

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

This map is immutable. If you want the map to be mutable, you have to add:

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

If you can't use Java 9, you're stuck with writing a similar helper method yourself or using a third-party library (like Guava) to add that functionality for you.

Solution 3

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?

Solution 4

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

Solution 5

Here's a simple class that will accomplish what you want

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]);
    }
}

And then to use it

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

This yields {a:1, b:2}

Share:
186,041

Related videos on Youtube

user387184
Author by

user387184

consulting and developing iOS iPhone apps, Android apps and WP Apps

Updated on July 08, 2022

Comments

  • user387184
    user387184 almost 2 years

    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.

  • user387184
    user387184 over 12 years
    That looks interesting. Is there a name for that? It looks like the matrix operations in Excel...
  • Eng.Fouad
    Eng.Fouad over 12 years
    @user387184 Yeah, they call it "double brace initializer". See this topic: stackoverflow.com/questions/924285/…
  • user387184
    user387184 over 12 years
    I just put it in my code and I get this warning/message in the line: "The serializable class does not declare a static final serialVersionUID field of type long". Can I just ignore that? what does this mean? Thanks
  • Eng.Fouad
    Eng.Fouad over 12 years
    @user387184 You can ignore it. See this topic: stackoverflow.com/questions/285793/…
  • Timo Türschmann
    Timo Türschmann about 8 years
    You should not use this method. It creates a new class for every time that you use it, which has much worse performance than just plainly creating a map. See stackoverflow.com/questions/924285/…
  • Micah Stairs
    Micah Stairs over 7 years
    This is disgustingly hacky.
  • Hot Licks
    Hot Licks over 7 years
    @MicahStairs - But it's only one statement.
  • Micah Stairs
    Micah Stairs over 7 years
    True, but this is the sort of code that I never hope to stumble across in production.
  • Hot Licks
    Hot Licks over 7 years
    @MicahStairs - I've seen worse.
  • GOXR3PLUS
    GOXR3PLUS over 7 years
    Omg i have searched for this today,how this code works? I have added it into the code for testing but i can't figure it out how it works internally... :)
  • idungotnosn
    idungotnosn over 7 years
    The reason I downvoted this is because it didn't explain that this creates a new class for every time that you use it. I think that people should be aware of the tradeoffs of doing it this way.
  • Chris Cirefice
    Chris Cirefice over 7 years
    @TimoTürschmann Seems that if I ever needed static initialization of a map like this, that it would also be static, eliminating the every time you use it performance penalty - you'd have that penalty once. I can't see any other time that one would want this kind of initialization without the variable being static (e.g., would anyone ever use this in a loop?). I may be wrong though, programmers are inventive.
  • ericn
    ericn about 7 years
    Guava is huge, I wouldn't use it for my Android app unless absolutely necessary
  • Vadzim
    Vadzim about 7 years
    Beware that ImmutableMap doesn't accept null keys or values.
  • Ar5hv1r
    Ar5hv1r about 6 years
    Please don't use this anti-pattern, it's actively dangerous and there are reasonable alternatives.
  • Ar5hv1r
    Ar5hv1r about 6 years
    @ericn ProGuard lets you exclude any parts of a library you aren't using.
  • Sourabh
    Sourabh over 5 years
    Excellent if you could use Java 9+. Also these factory method returns immutable map.
  • Ariel Grabijas
    Ariel Grabijas about 5 years
    Another problem with this solution is that it can lead to memory leaks. Since it creates anonymoys class with reference to the instance of the owning object, leak can occur when anonymous inner class is returned and held by other objects.
  • vikramvi
    vikramvi about 4 years
    After adding 10 entries, it throws strange error "can not resolve method", is this bug with this method ?
  • jolivier
    jolivier about 4 years
    @vikramvi yes If you look at the documentation Map.of is only done up to 10 entries since it is quite laborious
  • juls
    juls almost 4 years
    This method shouldn't be used since the implementation is not type safe! Example: Map<Integer, String> map1 = mapOf(1, "value1", "key", 2, 2L);
  • R. Oosterholt
    R. Oosterholt almost 4 years
    Well, I expect the programmer which defines Map<Integer, String>, to also supply those types...