JEP 186: Collection Literals
John Hendrikx
hjohn at xs4all.nl
Tue Jan 14 17:47:16 PST 2014
I'm very much in favor of either:
- a full fledged extensible system that will work with any Class that
provides specific (optionally static) constructors/methods
- just some helper methods where you'd expect them, ie:
ArrayList.of("A", "B", "C"), and some extra magic for maps that deal
with their arguments in an odd/even fashion (not type unfortunately)
Other than that, I could voice some crazy idea like supporting multiple
ellipsis / parameter groups:
HashMap(K... keys, V... values) {} // constructor
new HashMap<String, Integer>("A", 2, "B", 3, "C", 4);
Or to only add a bit of syntactic sugar, in combination with an
annotation/interface for value-holder type classes (or for special
initialization constructors) and additional constructors for the
Collection classes:
1) Add the following constructors to HashMap and ArrayList (and others):
@Initializer HashMap(Entry<K,V>... entries)
@Initializer ArrayList(Value<T>... values)
where Entry and Value are classes with a public constructor:
@ValueHolder
class Entry<K,V> {
Entry(K k, V v) {}
}
@ValueHolder
class Value<T> {
Entry(T t) {}
}
2) Add the following syntax sugar:
HashMap<String, Integer> map1 = ({"A", 1}, {"B", 2});
HashMap<String, ArrayList<Integer>> map2 = ({"A", {1, 2, 3, 4}},
{"B", {2, 4, 6, 8}});
transforms to:
HashMap<String, Integer> map = new HashMap<>(new Entry<String,
Integer>("A", 2), new Entry<String, Integer>("B", 3));
HashMap<String, Integer> map = new HashMap<>(new Entry<String,
ArrayList<Integer>>("A", new ArrayList<Integer>(new Value(1), new
Value(2), new Value(3), new Value(4))), new Entry<String,
ArrayList<Integer>>("B", new ArrayList<Integer>(new Value(2), new
Value(4), new Value(6), new Value(8))));
The transformation above is fully driven by the types specified on the
lhs and the annotation on the constructors and/or their value-holders.
It could basically be done right now (with IDE support), apart from the
needed changes to HashMap and ArrayList. It is fairly flexible I think
as well, and certainly does not need to be limited to Collection
classes, ie:
HBox hbox = ({new Button("OK"), new Button("Cancel")});
transforms to:
HBox hbox = new HBox(new HBox.ValueHolder(new Button("OK")), new
HBox.ValueHolder(new Button("Cancel")));
where HBox.ValueHolder is whatever HBox decides to use for its value-holder.
This is hardly light-weight though, and it would be worth investigating
if this could be done more direct or to see if the compiler could handle
optimizing away the value holders.
--John
On 14/01/2014 18:23, Brian Goetz wrote:
> This is a very valid point, and one that has been raised before -- that
> maybe this doesn't need a language feature, that maybe simply some
> library changes would be enough.
>
> In fact, since the goal at this point is to discuss whether we should
> move forward or not with the /exploration/ of the language feature, let
> me restrict the discussion to this point: is this something that needs a
> language feature, or would library support be enough? Bear in mind that
> the cost of even a simple language feature is probably 100x that of a
> comparable library feature, cost-benefit is an important consideration.
>
> On 1/14/2014 12:02 PM, Klaus Malorny wrote:
>> On 14.01.2014 17:33, Nick Williams wrote:
>> > I think we should also try to keep the Java Unified Expression Language in
>> > mind while designing this. Java EE 7 added lambda expressions to JUEL. Can
>> > you imagine how confusing it would have been if they had defined a different
>> > lambda syntax than Java 8? They didn't, though. They made the syntax mirror
>> > Java 8 lambdas.
>> >
>> > JUEL also has collection literals now, and I think it would be foolish to
>> > define a literal syntax different than that defined in JUEL. It will make
>> > developers' lives more difficult. The JUEL syntax is simple and I think it
>> > would work perfectly in Java as well:
>> >
>> > List: [ 1, 2, 3 ] Set: { 1, 2, 3 } Map: { "one" : 1, "two" : 2, "three" : 3
>> > }
>> >
>> > If we, for example, make Lists use curly braces in Java when they already use
>> > square brackets in JUEL, that would be unfortunate.
>> >
>> > Nick
>> >
>>
>>
>> Hi,
>>
>> if I may add my two cents: I have solved the problem for me by
>>
>> - having a static setOf (...) method to construct sets, which
>> is imported via static import if need be
>> - having a static mapOf (key, value) method which is the start
>> of a call chain, ending with map (), which returns the constructed
>> map,
>>
>> e.g. Map<String, Integer> map = mapOf ("one", 1).put ("two", 2).
>> put ("three", 3).map ();
>>
>> Overloaded and alternative methods allow me to create unmodifiable sets and
>> maps, including EnumMaps, also to perform some additional checks for EnumMaps
>> (e.g. whether all keys occur). Similar could be done for lists, of course.
>>
>> So while I do not dislike collection literals, I just want to point out that the
>> keyboard typing benefit isn't that great IMHO.
>>
>> Regards,
>>
>> Klaus
>>
More information about the lambda-dev
mailing list