We are encountering problems when trying to use Scala code from Java. We are looking for a way to auto-bridge the various Scala and java collections without explicitly having to explicitly convert in our our Java code. When there are very few places it is reasonable to do it, but if it is wide spread and constantly adding new scala classes it just becomes impractical.
For instance in our Scala code we have some classes like this (many of these):
case class Product(id: String, group: String, attributes : Map[String,String])
def fooWithProducts(products : Seq[Product]) = ...
// create a product
val p1 = Product("id1","group1", Map("attribute1" -> "value1","attribute2" -> "value2")
val p2 = Product("id2","group1", Map("attribute1" -> "value1","attribute2" -> "value2")
fooWithProducts(Seq(p1,p2))
when we want write similar code in Java it becomes very cumbersome and we need to add a lot of auxillary boiler plate all over the place:
// JAVA
// create a product
HashMap<String, String> attributes = new HashMap<String, String>();
attributes.put("my-attribute","my-value");
// create a scala collection
scala.collection.immutable.Map<String, String> scalaAttributes = Conversions.toScalaImmutableMap(attributes);
// create a product
Product p = Product("id","group",scalaAttributes)
// create a scala sequence of product
ArrayList<Product> dataFeedsProducts = new ArrayList<Product>();
dataFeedsProducts.add(Product);
Seq<Product> seq = JavaConversions.asScalaBuffer(dataFeedsProducts).seq();
fooWithProducts(seq)
// SCALA helpers
public class Conversions {
//https://stackoverflow.com/questions/11903167/convert-java-util-hashmap-to-scala-collection-immutable-map-in-java/11903737#11903737
@SuppressWarnings("unchecked")
/**
* Transforms a java map to a scala immutable map
*/
public static <K, V> scala.collection.immutable.Map<K, V> toScalaImmutableMap(java.util.Map<K, V> javaMap) {
final java.util.List<scala.Tuple2<K, V>> list = new java.util.ArrayList(javaMap.size());
for (final java.util.Map.Entry<K, V> entry : javaMap.entrySet()) {
list.add(scala.Tuple2.apply(entry.getKey(), entry.getValue()));
}
final scala.collection.Seq<Tuple2<K, V>> seq = scala.collection.JavaConverters.asScalaBufferConverter(list).asScala().toSeq();
return (scala.collection.immutable.Map<K, V>) scala.collection.immutable.Map$.MODULE$.apply(seq);
}
/**
* transforms a scala map to the java counterpart
*/
public static <K,V> java.util.Map<K,V> mapAsJavaMap(scala.collection.immutable.Map<K,V> m) {
if (m == null) {
return null;
}
return JavaConversions.mapAsJavaMap(m);
}
public static<A> Seq<A> asScalaSeq(java.util.List<A> l) {
return JavaConversions.asScalaBuffer(l).toSeq();
}
}
We are wondering if there is a way to annotate the Scala code or auto-generate equivalent Java counterpart interfaces for these Scala idioms.