krazycoder / google-collections

Automatically exported from code.google.com/p/google-collections
Apache License 2.0
0 stars 0 forks source link

Creating a map from varargs #232

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Unfortunately, Java still lacks a native syntax for creating lists and maps
(e.g. `List myList = [0, 1, 1, 2, 3, 5, 8, 13]`). However,
`Collections.newArrayList(T... elements)` and friends allow for a rather
comfortable way to create a list pre-filled with some items (e.g. for unit
tests). For maps, though, such a method is missing.

My attempt to creating a map with some entries in one method call is to
have it accept an even number of varargs which are then treated as
key/value pairs (similar to Python's `dict()` constructor which accepts a
list of 2-tuples, but adopted to Java's expressiveness/syntactical limits).

An example call: `newHashMap("firstname", "Hiro", "lastname",
"Protagonist", "age", 26);` (age is guessed), result (returned by
`.toString()`): `{firstname=Hiro, lastname=Protagonist, age=26}`.

Here is my attempt at an implementation, in this case for a LinkedList
(though other types like HashMap and TreeMap should be provided, too). On a
side note, I'm not that confident in creating generic methods, so please
tell me if I'm doing something wrong/dangerous/inappropriate etc.

  private static <T> Map<T, T> newLinkedHashMap(T... keysAndValues) {
    if (keysAndValues.length % 2 != 0) {
      throw new IllegalArgumentException("The number of arguments must be a
multiple of 2.");
    }

    Map<T, T> map = new LinkedHashMap<T, T>();
    Iterator<T> it = Arrays.asList(keysAndValues).iterator();
    while (it.hasNext()) {
      map.put(it.next(), it.next());
    }
    return map;
  }

What do you think about the idea itself and an inclusion into Google
Collection as a complement to `newArrayList(T... elements)` et al.?

Regards,
Jochen Kupperschmidt

Original issue reported on code.google.com by j...@nwsnet.de on 8 Sep 2009 at 10:30

GoogleCodeExporter commented 8 years ago
Wait for JDK 7. Its there. Checkout Project Coin.

Yogesh

Original comment by sinhay...@gmail.com on 8 Sep 2009 at 1:52

GoogleCodeExporter commented 8 years ago
The same applies for `newArrayList()` and friends. `newFooMap()` still fits 
here, too.

Also, JDK 7 is quite far away. Shifting current production applications (some 
of them
don't even use JDK 6) to it might not happen in the next two years or so for 
many
projects. Which is where Google Collections comes into play. Which is why I 
made this
suggestion.

Original comment by j...@nwsnet.de on 8 Sep 2009 at 2:26

GoogleCodeExporter commented 8 years ago
Look at ImmutableMap and ImmutableSortedMap, which include factory methods and
builders that do what you want. The vararg methods handle up to 5 key-value 
pairs,
and the builders can create larger maps.

Your newLinkedHashMap code doesn't support the common case in which the key 
type and
value type differ. For that reason, we can't supply a varargs method that 
supports
arbitrary sizes.

I'm closing this issue, since the library already has the map factory methods 
that
make sense.

Original comment by jared.l....@gmail.com on 8 Sep 2009 at 5:13

GoogleCodeExporter commented 8 years ago
but may I add: very nice example. :) thanks for reminding me of that great book.

Original comment by kevin...@gmail.com on 8 Sep 2009 at 9:10

GoogleCodeExporter commented 8 years ago
jared.l.levy: Indeed, though being immutable is not sufficient in all cases. I 
guess
the limit of 5 vararg pairs is somewhat arbitrary (defining additional 
overloaded
methods with a greater number however is no actual solution to me, so I don't 
request
that)? But I like the Builder interface!

`newLinkedHashMap()` does work using `<String, Object>` as key/value types, but 
that
probably uses Object in the end for everything, which isn't really desirable, 
but is
sufficient in my case to create comparison data maps for unit testing.

kevinb9n: You're welcome :D

Original comment by j...@nwsnet.de on 9 Sep 2009 at 8:32