Better Map Constructor

21,608

Solution 1

No, there isn't, but I wrote a method to do exactly this, inspired by Objective-C NSDictionary class:

public static Map<String, Object> mapWithKeysAndObjects(Object... objects) {

    if (objects.length % 2 != 0) {
        throw new IllegalArgumentException(
                "The array has to be of an even size - size is "
                        + objects.length);
    }

    Map<String, Object> values = new HashMap<String, Object>();

    for (int x = 0; x < objects.length; x+=2) {
      values.put((String) objects[x], objects[x + 1]);
    }

    return values;

}

Solution 2

There's always double-brace initialization:

Map<String, String> map = new HashMap<String, String>(){{
    put("a", "apple"); put("b", "bear"); put("c", "cat");}};

There are problems with this approach. It returns an anonymous inner class extending HashMap, not a HashMap. If you need to serialize the map then know that serialization of inner classes is discouraged.

Solution 3

You could use ImmutableMap.Builder from Google collections library.

Solution 4

Java 9 adds Map.of, such as:

Map<String, String> map = Map.of("a", "apple", "b", "bear", "c", "cat");

Up to 10 entries are supported. For more entries you can use the overload taking Entry:

Map<String, String> map 
    = Map.ofEntries
        (Map.entry("a", "apple")
        , Map.entry("b", "bear")
        , Map.entry("c", "cat"));

Note that these methods do not return a HashMap. It returns an optimized immutable map.

Solution 5

You could always use double brace initialization:

Map<String, String> map = new HashMap<String, String>() {{
    put("foo", "bar");
    put("baz", "qux");
}}

But bear in mind this might not be efficient according to these answers.

Share:
21,608
Ben Noland
Author by

Ben Noland

I am the creator and owner of collabedit.com and codinghire.com. I have also been a full time software developer for about 10 years.

Updated on December 09, 2020

Comments

  • Ben Noland
    Ben Noland over 3 years

    Is there a more streamlined way to do the following?

    Map<String, String> map = new HashMap<String, String>();
    map.put("a", "apple");
    map.put("b", "bear");
    map.put("c", "cat");
    

    I'm looking for something closer to this.

     Map<String, String> map = MapBuilder.build("a", "apple", "b", "bear", "c", "cat");
    
  • 700 Software
    700 Software almost 13 years
    Most likely caveat is that will not be Serializable.
  • home
    home almost 13 years
    +1. interesting, I did not see that before. Question is if it makes life really easier :-)
  • Eugene Kuleshov
    Eugene Kuleshov almost 13 years
    This is generally not a good idea for any kind of production code. It also creates anonymous class every time.
  • Nathan Hughes
    Nathan Hughes almost 13 years
    @George: it's not that it isn't Serializable, it's that a compiler warning complains it doesn't have a serialUID.
  • Eugene Kuleshov
    Eugene Kuleshov almost 13 years
    This breaks Java generics type safety.
  • Amir Raminfar
    Amir Raminfar almost 13 years
    I don't see why you would want to reinvent ImmutableMap.of(...) in google's collection
  • 700 Software
    700 Software almost 13 years
  • Maurício Linhares
    Maurício Linhares almost 13 years
    I would reinvent to avoid adding yet another unnecessary library full of unnecessary classes when all i want is a single method.
  • Maurício Linhares
    Maurício Linhares almost 13 years
    Great idea @Robert, added it now.
  • Eugene Kuleshov
    Eugene Kuleshov almost 13 years
    Maurício, looking at number of iterations in your code, you had saved some time and bugs by using a proven library. Besides, you may find it actually useful and it would help toy write a cleaner and safer code.
  • Maurício Linhares
    Maurício Linhares almost 13 years
    Eugene, that's a matter of opinion, I don't find it useful to add a library instead of typing 15 lines of code.
  • Paŭlo Ebermann
    Paŭlo Ebermann almost 13 years
    The deserialized map will have the original values for these keys, even if changed later (before serializing).
  • Jochen Bedersdorfer
    Jochen Bedersdorfer almost 13 years
    whoever came up with the name 'double brace initialization' should be shot. This is a valid declaration of an anonymous class combined with a non-static initializer block.
  • Mladen Adamovic
    Mladen Adamovic over 9 years
    Guava is bloated v18 adds 2.5MB jar file (without sources), if you are going to use 1% of it, I'd rather use custom sollutions like this one for faster compile/deploy times.