Looking the other day through the JDK Enhancements Proposals (aka “JEP“) I came across JEP-269: “Convenience Factory Methods for Collections”. Oh hello, where have you been all these previous JDK releases? π It seems finally the Java world has woken up to what other JVM languages (and not only!) have been offering for a while: an easy way to declare and initialize a collection.
According to the JEP summary, this JEP aims to:
Define library APIs to make it convenient to create instances of collections and maps with small numbers of elements, so as to ease the pain of not having collection literals in the Java programming language.
That sounds cool — I dig π To be honest, one of the reasons why I turned my attention to Groovy language in the first place was that it made such things so easy:
def set = ['1', '2', '3'] as Set |
or
def list = ['x', 'y', 'z'] |
or
def map = ['a':1, 'b':2] |
Tell me you don’t prefer this to the Java equivalent:
Set<String> set = new HashSet<String>(); set.add( '1'); set.add('2'); set.add('3'); |
Or the (even worse) other one:
Set set = new HashSet<>(Arrays.asList("a", "b", "c")); |
(I say the above one is even worse because you go through creating a List
first to create a Set
— take a hammer like this and beat your GC!)
Funny enough the JEP gives a lot of examples around Set
‘s because it’s such a classic missing feature in JDK π
So what does this JEP propose? Well, at first glance it is a very simple improvement: adding a static of(...)
factory methods to (most) collection classes which accepts a list of varags. Such that one can write:
Set<String> set = Set.of("a", "b", "c"); List<Integer> list = List.of( 1, 2, 3); |
Brilliant! Not as condensed as GroovyΒ but still a huge step in the right direction!
What about maps? Well, this is a bit trickier, the JEP suggests a set of fixed number of args factory methods:
Map<String,String> map = Map.of("a", "b", "c", "d"); |
This would be equivalent in Groovy to:
def map = ["a":"b", "c":"d"] |
The key in the above statement is fixed number of arguments. That’s all good and they seem to suggest providing implementations for up to 6 arguments — therefore 3 entries. But what happens past 3 entries then?
Luckily the JEP doesn’t go to suggest providing methods for 8,10, 12 or 14 (7 entries) methods — and doing it via varargs would be a mess as one has to validate the number of args at compile time and that turns into a mess! Instead, they (neatly!) suggest another factory method:
Map.ofEntries( Map.Entry<K,V> ...) |
This would allow us to supply N Map.Entry
objects in one line. And of course to sweeten the deal they also have a nice factory method for Map.Entry
:
Map.Entry<K,V>entry = Map.entry( K k, V v); |
So now one can write (again, not as succinct as Groovy but better than the hoops we jump through nowadays in Java):
Map<String,String> map = Map.ofEntries( Map.entry("a", "b"), Map.entry("c", "d"), Map.entry("f", "g"), Map.entry("h", "i"); |
And of course you can static import Map.entry
and then just write:
Map<String,String> map = Map.ofEntries( Map.entry("a", "b"), Map.entry("c", "d"), Map.entry("f", "g"), Map.entry("h", "i"); |
As I said in the beginning of this post: where have you been all these JDK releases, JEP-269? π
just use Scala already mate π
Provide static factory methods on the collection interfaces that will create compact, unmodifiable collection instances. The API is deliberately kept minimal.