Fun with Java Generics: A Fluent Map

Are you sick of creating maps with all the redundant syntax like in the example below?


Map map = new HashMap();
map.put(1, "ONE");
map.put(2, "TWO");
map.put(3, "THREE");

With the usage of some advanced Java 5 features, we can make map creation simpler:


Map(
   o(1, "ONE"),
   o(2, "TWO"),
   o(3, "THREE"),
);

Too make this happen you need the class that is listed below. Just import the methods Map and o statically and then lets rock!


public class FluentMap {

    public static  Map Map(Tuple... entries) {
        Map map = new HashMap();

        for (Tuple entry : entries) {
            map.put(entry.t1, entry.t2);
        }
        return map;
    }

    public static  Tuple o(T1 o1, T2 o2) {
        return new Tuple(o1, o2);
    }

    public static class Tuple {
        private T1 t1;
        private T2 t2;

        public Tuple(T1 t1, T2 t2) {
            this.t1 = t1;
            this.t2 = t2;
        }
    }
}

The trick here is that Java supports type inference in static methods. That is why you don’t need to specify any type.

Diese Icons verlinken auf Bookmark Dienste bei denen Nutzer neue Inhalte finden und mit anderen teilen können.
  • MisterWong
  • Y!GG
  • Webnews
  • Bloglines
  • blogmarks
  • Blogosphere News
  • De.lirio.us
  • email
  • MySpace
  • Technorati

8 Kommentare zu „Fun with Java Generics: A Fluent Map“

  1. Bravo, that’s a good one! For a simple uni-type map (I use them a lot) something like this may be useful:

    public static Map newHashMap(final T… data) {
    if (data.length % 2 != 0) {
    throw new IllegalArgumentException(“Number of params must be a multiple of 2″);
    }
    final Map result = new HashMap();
    for (int i = 0; i < data.length; i+=2) {
    result.put(data[i], data[i + 1]);
    }
    return result;
    }

  2. Oh no! The blog ate my angle bracket’ed text. :-)

  3. Octavian sagt:

    I don’t think I’ve seen anything (Java code I mean) more beautiful in the last year or so…

  4. Why did you create a new Tupple class? Map.Entry is is sufficient for this case, isn’t it?

    public class FluentMap {

    public static Map Map(Entry… entries) {
    Map map = new HashMap();

    for (Entry entry : entries) {
    map.put(entry.getKey(), entry.getValue());
    }
    return map;
    }

    public static Entry o(T1 o1, T2 o2) {
    return new SimpleEntry(o1, o2);
    }

    }

  5. GHad sagt:

    Can also be done with 3 classes + 1 interface without static imports:

    class TestClass implements FluentMaps {

    @SuppressWarnings(“unchecked”)
    static void doSomething() {

    System.out.println(
    Map.one(“key”, “value”)
    );

    System.out.println(
    Map.some(
    “key1″, “value1″,
    “key2″, “value2″
    )
    );

    System.out.println(
    Map.many(
    Key.value(“key1″, 1),
    Key.value(“key2″, 2)
    )
    );

    System.out.println(
    Map.builder(“key1″, “value1″)
    .put(“key2″, “value2″)
    .put(“key3″, “value3″)
    .build()
    );
    }
    }

    If interested, mail me…

    Greetz,
    GHad

  6. Omar sagt:

    That’s exactly the same behaivour that you get with google collections and static imports.
    Methos like Maps.newHashMap() and newHashMap() are available in this library, or a more elegant option.

    ImmutableMap map2 = mapOf("key1", "value1", "key2", "value2")

    Take a look in this nice article: http://codemunchies.com/2009/10/beautiful-code-with-google-collections-guava-and-static-imports-part-1/

  7. I actually implemtend this on a little project a couple of months ago:

    Project:
    http://code.google.com/p/fluentjava/

    The example:
    http://code.google.com/p/fluentjava/wiki/GettingStarted#Maps

    Funny thing: the api even has a Map called FluentMap (which does a bit more than just being fluent):
    http://fluentjava.googlecode.com/svn/javadoc/apidocs/org/fluentjava/collections/FluentMap.html

Kommentieren

Spam protection by WP Captcha-Free