Wednesday, August 19, 2009

Almost literals - Initializing Java collections

Dynamic languages like Python and Ruby provide built-in syntax to express common data structures as literals. However, Java provides literal syntax only for arrays.

Although not pretty, here is how you can quickly initialize Java collections:


import java.util.*;

public class Literals {
private static class HashMapNow<K, V> extends HashMap<K, V> {
public HashMapNow<K, V> with(K key, V value) {
put(key, value);
return this;
}
}

public static void main(String[] args) {
// initialize a list
List<String> list = Arrays.asList("a", "b", "c", "c");

// initialize a set
Set<String> set = new HashSet<String>(Arrays.asList("a", "b", "c", "c"));

// initialize a map
Map<String, String> map = new HashMapNow<String, String>()
.with("a", "1")
.with("b", "2")
.with("c", "3")
.with("c", "4");

// print them all
System.out.println(list);
System.out.println(set);
System.out.println(map);
}
}


2009 Aug 25 [Update]: As suggested by Eric (in comments below), the initialization can be done in the static block - though it is admittedly quirkier. Cleaner options are available in Google Collections and LambdaJ.

2 comments:

  1. Definitely, not a strong reason to make the cross over :)

    ReplyDelete
  2. An uglier version which you shouldn't use if you are ever calling equal or hashCode on the map is:

    Map<String, String> map =
    new HashMap<String, String>() {
    {put("a", "1");
    put("b", "2");
    put("c", "3");
    put("c", "4");}
    };

    This uses the little-known 'instance initializer' syntax. The Google Collections library provides map builders to do the equivalent.

    ReplyDelete

Disqus for Char Sequence