0

I'm trying to use a target type to specify a collection literal's type:

val java.util.HashMap<String,String> map = #{
  'a' -> 'b'
}

But I get:

HelloWorld.java:212: error: incompatible types: Set<Object> cannot be converted to HashMap<String,String>
    final HashMap<String, String> map = Collections.<Object>unmodifiableSet(CollectionLiterals.<Object>newHashSet(_mappedTo, _mappedTo_1, _mappedTo_2, _mappedTo_3));

Note that this is a java compilation error, not an Xtend one. For some reason Xtend is trying to generate a Set even though the target type is a HashMap.

However, if I change the target type to Map, it generates a map as expected.

The Xtend docs say

In addition xtend supports collection literals to create immutable collections and arrays, depending on the target type

so I thought I could control the type of unmodifiable map I get back.

Xtend version: 2.9.0

Kelvin
  • 20,119
  • 3
  • 60
  • 68

2 Answers2

1

You cannot do that way you want - implicit conversion won't change the type of map literal for you (bug you are getting is compiler artifact - it gets confused between set of pairs and map literals). What you can do instead is

val map = Maps.newHashMap(#{
        'a' -> 'b'
    })

which is probably even less typing ;) Maps is from com.google.common.collect, which you will get together with xtend in dependencies.

Artur Biesiadowski
  • 3,595
  • 2
  • 13
  • 18
  • Nice. After seeing your answer I found a [similar solution](http://stackoverflow.com/a/7345751/498594) for pure java. – Kelvin Jul 13 '16 at 16:03
1

That quote from Xtend doc:

In addition xtend supports collection literals to create immutable collections and arrays, depending on the target type.

means either a collection, or an array — since for both the literal syntax is the same:

val myList = #['Hello', 'World']
val String[] myArray = #['Hello', 'World']

Sets and maps have both a different syntax, so no need to specify the target type here:

val mySet = #{'Hello', 'World'}
val myMap = #{'a' -> 1, 'b' -> 2}

If you insist on the target type, use e.g. newHashMap:

val myHashMap = newHashMap('a' -> 1, 'b' -> 2)
charlie
  • 1,478
  • 10
  • 20