Building your own literals in Java – Lists, and Arrays

The rise of some ‘new’ languages like Ruby, Groovy and Scala is (among other things) accompanied with discussions about the verbosity of some established languages, especially Java.
For example there are not few voices, complaining about the boilerplate code that you have to write (and read) when it comes to the declaration and instantiation of collection types in Java.

In Java, instantiation of a List and filling it with some Strings are typically separated in multiple steps:

List<String> myList = new ArrayList<String>();
myList.add( "a" );
myList.add( "java" );
myList.add( "list" );

If you want to declare a similar List of Strings in Groovy, you can use it’s literal syntax:

[ "a", "groovy", "list" ]

You’ll find a similar syntax in Scala, where you mark your list literal by preceding it with the ‘keyword’ List:

List( "a", "scala", "list" )

Ok, there’s really loads of boilerplate code in the before mentioned Java example. We could use an anonymous, static constructor, to instantiate and fill the List (knowing that we obtain an instance of a new anonymous subtype of List with all consequences i.e. in regard to equals() or hashCode() ), but that’s still verbose comparing to Groovy or Scala:

new ArrayList<String>(){{
	add( "a" );
	add( "java" );
	add( "list" );
}};

In the following section i’ll show you another way that will make use of static imports and Generics, providing a way of declaring a List in Java, having a literal form just like Scala’s syntax. Note that i will use some unusual names for some classes and methods for the sake of similarity to Scala.

Write once, use everywhere

Static imports provide a way to sort of introduce new ‘keywords’ you can use within your source. So we now will introduce a new keyword ‘List’, responsible for creating a new Instance of a List, accepting an arbitrary number of elements that are pushed to the List immediately.
Therefore we define a static method ‘List’ (yes, the first character is unusually an upper case – i told you so) and settle this static method in a class named ‘collection’ (as a kind of chargeback, now using a lower case):

package literal;

public class collection {

	public static <T> List<T> List(T...elems){
		return Arrays.asList( elems );
	}
}

That’s it! Now we can use this literal form of List instantiation wherever we want, having the same syntax as in Scala:

import static literal.collection.List;
import static system.io.*;

public class CollectionDemo {

	public void demoList(){

		List<String> slist = List( "a", "b", "c" );

		List<Integer> iList = List( 1, 2, 3 );

		for( String elem : List( "a", "java", "list" ) ){
			System.out.println( elem );
		}
	}
}

As you can see, declaring a filled List with some elements is as simple and concise as in Scala. Except for the static import of our ‘keyword’, there’s no difference to Scala (now you may see, why we declare the class using a starting lower case and the method with a starting upper case – the static import reads like importing a Type named List from package collection. That’s in fact a fake and not honest. Of course you can name those however you want, observing the conventions. I’ve only named them in that way in order to appear as funky or groovy like the hip languages today ;o)).
Thanks to the generic definition of List (remember, it’s a method), we can instantiate a List with elements of an arbitrary type!

Same scheme is of course possible for Arrays and other kind of Collections, like Set or Queue – we only have to extend our collection class with some corresponding static factory methods:

package literal;

public class collection {
	...
	public static <T> T[] Array(T...elems){
		return elems;
	}

	public static <T> Set<T> Set(T...elems){
		return new HashSet<T>( List( elems ) );
	}
	...
}

Again, we now could create an Array of an arbitrary type like in Scala:

import static literal.collection.Array;
import static system.io.*;

public class CollectionDemo {
	...
	public void demoArray(){

		String[] sArray = Array( "a", "b", "c" );

		Integer[] iArray = Array( 1, 2, 3 );		

		for( String elem : Array( "a", "b", "c" ) ){
			println( elem );
		}
	}
}

Now if you ask where that println is coming from (another area, where some voices complaining to use boilerplate System.out.println instead of simply println) – it’s just another new ‘keyword’, resting in class (!) system.io.

As you may have seen, there’s noting special about that solution. Using static imports gives you the chance to ‘pimp up’ Java in some areas.
In this post we only scratched the surface in making Java more concise by building our own literals for List and Array.
In the next one i’m gonna show you how to instantiate and fill a Map without much boilerplate code (an example, that’s quoted most, when blaming Java about it’s verbosity in the field of literals)

Admitted, there are some areas, where you can’t achive the same kind of conciseness (yet), especially when it comes to function types, closures or method extentions (using implicits in Scala or a kind of meta object protocoll and true message sending like in Ruby or Groovy) but Java’s not so rigid that it’s completely inflexible in achiving new forms towards ‘literal programming’.

Maybe before complaining about Java’s verbosity and lack of conciseness, we should sit and think a minute what’s possible with the given features.

Posted in java. 25 Comments »

25 Responses to “Building your own literals in Java – Lists, and Arrays”

  1. afsina Says:

    well, a new syntax does not hurt, but you are giving missing information about Java.

    List list=asList(“Blah”,”Bleh”);

    works for me (Arrays.asList() and static imports.)

  2. afsina Says:

    Also,
    out.println() is always an option with tatic imports.

  3. Mario Gleichmann Says:

    afsina,

    you’re completely right!
    I think at the core of this post should stand the statement, that Java isn’t that bad when it comes to reducing boilerplate code. Static imports are a powerfull way to reduce some of it.

    I’ve hidden the original methods behind an own factory method, to show that Java can stand against such ‘hip’ languages like Scala while presenting the same syntax in Java.

    My next post will show a way on how to declare a Map in a more literal way, not only achievable by using static imports – i would be glad if you’ll take a look and give some critical comments.

    Greetings

    Mario

  4. afsina Says:

    well, your helper methods are good. i use something similar, actually i think including GoogleCollections lots of library has similar classes and static methods (They name them Lists, Maps, Sets etc.). Truth is, initialization operations are not as common as people think. They are mostly used in small examples and test methods. But still it would justify making them easier. i would like to see your Map declaration.

  5. Pages tagged "literal" Says:

    […] = “34d024″; var mooter_wrapper_url=””; var run_method = “onload”; var mooter_target = “0”; Building your own literals in Java – Lists, and Ar… saved by 1 others     honeykisses4u bookmarked on 01/14/08 | […]

  6. Building your own literals in Java - Tuples and Maps « brain driven development Says:

    […] literals in Java – Tuples and Maps January 15, 2008 — Mario Gleichmann As hinted in my last post about literals in Java, we’ve only scratched the surface on that issue. In this entry it […]

  7. Declarative programming: a Range type for Java « brain driven development Says:

    […] declarative style, we’ll again put a simple factory method to our collection class (see the previous […]

  8. Mike w Says:

    Be aware that the Arrays.asList is not returning a true ArrayList. Take a look inside the class, and you’ll see that asList is returning an internally defined class called ArrayList that really only wraps an array.

    Try adding an item to the ArrayList returned from Arrays.asList, and you’ll see what I mean

  9. ruslanv Says:

    Mike w is right, you’ll get immutable list in this way
    inconvenience beats beauty of solution

  10. Denver Small Says:

    You don’t give an example of the type: list[a] = “element”; I wanted to know if java does this like html

  11. List Building Tips Says:

    Hi! Thank you for this unbelievable useful article! I’m just 20 so it helps me a lot!

  12. list+building Says:

    It’s hard to come by well-informed people on this subject, but you sound like you know what you’re talking about! Thanks

  13. tilt-shift photography Says:

    I have read a few good stuff here. Definitely worth bookmarking for revisiting.

    I surprise how much effort you set to make this type
    of wonderful informative site.

  14. Oxitamin Diet Says:

    Thanks for sharing your thoughts on loss diet plan.
    Regards

  15. Get Rid of Herpes Review Says:

    I have to thank you for the efforts you have put in penning this website.
    I’m hoping to see the same high-grade content by you later on as well. In fact, your creative writing abilities has motivated me to get my own website now 😉

  16. How to: Efficiency of Java "Double Brace Initialization"? | SevenNet Says:

    […] Gleichman describes how to use Java 1.5 generic functions to simulate Scala List literals, though sadly you wind up […]

  17. Solution: Efficiency of Java "Double Brace Initialization"? #dev #it #computers | Technical information for you Says:

    […] Gleichman describes how to use Java 1.5 generic functions to simulate Scala List literals, though sadly you wind up […]

  18. Fixed Efficiency of Java "Double Brace Initialization"? #dev #it #asnwer | Good Answer Says:

    […] Gleichman describes how to use Java 1.5 generic functions to simulate Scala List literals, though sadly you wind up […]

  19. Efficiency of Java “Double Brace Initialization”? - QuestionFocus Says:

    […] Gleichman describes how to use Java 1.5 generic functions to simulate Scala List literals, though sadly you wind up […]

  20. Java“双括号初始化”的效率?|java问答 Says:

    […] Gleichman描述了如何使用Java […]

  21. Efficiency of Java "Double Brace Initialization"? Says:

    […] Gleichman describes how to use Java 1.5 generic functions to simulate Scala List literals, though sadly you wind up […]


Leave a comment