2012-08-10 39 views

Respuesta

0

¿Puede proporcionar una llamada de API adicional que tome/proporcione un java.util.Map convertido utilizando JavaConverters?

class Example { 
    import scala.collection.JavaConverters._ 
    def fromMap(m:Map[...]) = ... 

    // generics etc. elided 
    def fromJava(m:java.util.Map) = { 
     fromMap(m.asScala.toMap) 
    } 
} 

Es posible que desee extraer la conversión y proporcionar un decorador (especialmente en lo que observo que está trabajando en una biblioteca de Scala). Nota dhg del comentario re. inmutabilidad.

17

Es perfectamente posible utilizar JavaConverters en Java de código no son sólo un par de aros adicionales para saltar a través de:

import java.util.HashMap; 
import scala.Predef; 
import scala.Tuple2; 
import scala.collection.JavaConverters; 
import scala.collection.immutable.Map; 

public class ToScalaExample { 
    public static <A, B> Map<A, B> toScalaMap(HashMap<A, B> m) { 
    return JavaConverters.mapAsScalaMapConverter(m).asScala().toMap(
     Predef.<Tuple2<A, B>>conforms() 
    ); 
    } 

    public static HashMap<String, String> example() { 
    HashMap<String, String> m = new HashMap<String, String>(); 
    m.put("a", "A"); 
    m.put("b", "B"); 
    m.put("c", "C"); 
    return m; 
    } 
} 

Podemos demostrar que esto funciona de la Scala REPL:

scala> val jm: java.util.HashMap[String, String] = ToScalaExample.example 
jm: java.util.HashMap[String,String] = {b=B, c=C, a=A} 

scala> val sm: Map[String, String] = ToScalaExample.toScalaMap(jm) 
sm: Map[String,String] = Map(b -> B, c -> C, a -> A) 

Pero, por supuesto, podría llamar fácilmente a estos métodos desde el código de Java.

+5

No existe un método "tomap" más. El código anterior no se puede compilar para Java 1.7 y Scala 2.11 :( –

+10

jdk 1.8, muestra el error "no se puede acceder a scala.Predef. $ Less $ colon $ less" – Freedom

0

Esto funcionó para mí con Java 1.8 y 2.12 Scala:

public static <K, V> scala.collection.immutable.Map<K, V> toScalaImmutableMap(java.util.Map<K, V> jmap) { 
    List<Tuple2<K, V>> tuples = jmap.entrySet() 
     .stream() 
     .map(e -> Tuple2.apply(e.getKey(), e.getValue())) 
     .collect(Collectors.toList()); 

    Seq<Tuple2<K, V>> scalaSeq = JavaConverters.asScalaBuffer(tuples).toSeq(); 

    return (Map<K, V>) Map$.MODULE$.apply(scalaSeq); 
} 
1

Mi solución para Java 1.7 y 2.11 Scala:

@SuppressWarnings("unchecked") 
private 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); 
} 
Cuestiones relacionadas