10

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");
Ben Noland
  • 34,230
  • 18
  • 50
  • 51
  • 2
    are the keys/values hardcoded like that? if so, why not something like loading a json string http://stackoverflow.com/questions/443499/json-to-map – David Jul 26 '11 at 17:30
  • possible duplicate of [Is there a best practice for writing maps literal style in Java?](http://stackoverflow.com/questions/3798083/is-there-a-best-practice-for-writing-maps-literal-style-in-java), and [initialize java HashSet values by construction](http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction) – Paŭlo Ebermann Jul 26 '11 at 19:18
  • @David: That is a great for constants. Especially for me because I use JSON frequently and often have the methods available. – 700 Software Jul 26 '11 at 19:54

5 Answers5

16

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.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • Most likely caveat is that will not be Serializable. – 700 Software Jul 26 '11 at 17:19
  • +1. interesting, I did not see that before. Question is if it makes life really easier :-) – home Jul 26 '11 at 17:19
  • This is generally not a good idea for any kind of production code. It also creates anonymous class every time. – Eugene Kuleshov Jul 26 '11 at 17:21
  • @George: it's not that it isn't Serializable, it's that a compiler warning complains it doesn't have a serialUID. – Nathan Hughes Jul 26 '11 at 17:22
  • @Nathan, I did not know you could serialize anonymous subclasses, but even then, I wouldn't recommend it. *["Serialization of inner classes (i.e., nested classes that are not static member classes), including local and **anonymous classes**, is strongly discouraged for several reasons."](http://download.oracle.com/javase/6/docs/platform/serialization/spec/serial-arch.html#4539)* – 700 Software Jul 26 '11 at 17:28
  • The deserialized map will have the original values for these keys, even if changed later (before serializing). – Paŭlo Ebermann Jul 26 '11 at 19:22
13

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;

}
Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158
9

You could use ImmutableMap.Builder from Google collections library.

Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
3

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.

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99
2

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.

Community
  • 1
  • 1
whirlwin
  • 16,044
  • 17
  • 67
  • 98
  • 1
    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. – Jochen Bedersdorfer Jul 26 '11 at 19:38