tutorial software fungicida examples blanquerna scala

software - scala vs java



Scala convert List[Int] a java.util.List (5)

¿Hay una buena manera en Scala para convertir una Lista [Int] a una java.util.List [java.lang.Integer]?

Estoy interactuando con Java (Thrift).

JavaConversions admite List -> java.util.List, y existen implicaciones entre Int -> java.lang.Integer, pero por lo que puedo decir, aún necesitaría un pase adicional para realizar la conversión manualmente.

val y = List(1) val z: java.util.List[Integer] = asList(y) map { (x: Int) => x : java.lang.Integer }


Aparentemente, necesitas ambas conversiones. Sin embargo, puede agruparlos en una única conversión implícita:

implicit def toIntegerList( lst: List[Int] ) = seqAsJavaList( lst.map( i => i:java.lang.Integer ) )

Ejemplo:

scala> def sizeOf( lst: java.util.List[java.lang.Integer] ) = lst.size scala> sizeOf( List(1,2,3) ) res5: Int = 3


Debido a que la representación subyacente de Int es Integer puede lanzar directamente a java.util.List[java.lang.Integer] . Le ahorrará una operación O (n) y algunas cosas implícitas.

import collection.JavaConversions._ class A { def l() = asList(List(1,2)).asInstanceOf[java.util.List[java.lang.Integer]] }

Entonces puedes usar Java de esta manera:

A a = new A(); java.util.List<Integer> l = a.l();

Tenga en cuenta que en 2.9.0, recibo una advertencia de desaprobación en asList (use seqAsJavaList en seqAsJavaList lugar)


Estaba intentando pasar un Map[String, Double] a un método Java. Pero el problema era que JavaConversions convierte el Map en un Map Java, pero deja el Double scala como está, en lugar de convertirlo a java.lang.Double . Después de unas pocas horas de búsqueda encontré [la respuesta de Alvaro Carrasco]) https://.com/a/40683561/1612432 ), es tan simple como hacer:

val scalaMap = // Some Map[String, Double] val javaMap = scalaMap.mapValues(Double.box)

Después de esto, javaMap es un Map[String, java.lang.Double] . Luego puede pasar esto a una función java que espera un Map<String, Double> y gracias a las conversiones implícitas, el Scala Map se convertirá en java.util.Map

En su caso sería lo mismo, pero con Int.box :

val y = List(1) val javay = y.map(Int.box)


Esto no tiene un implícito en la capa más externa, pero me gusta este enfoque genérico y lo he implementado para un par de tipos de colecciones (Lista, Mapa).

import java.util.{List => JList} import scala.collection.JavaConverters._ def scalaList2JavaList[A, B](scalaList: List[A]) (implicit a2bConversion: A => B): JList[B] = (scalaList map a2bConversion).asJava

Como una conversión implícita de Int a Integer es parte de lib estándar, el uso en este caso se vería así:

scalaList2JavaList[Int, Integer](someScalaList)

En la otra dirección!

(Ya que tengo estos disponibles de todos modos, ya que fueron mis implementaciones originales ...)

import java.util.{List => JList} import scala.collection.JavaConversions._ def javaList2ScalaList[A, B](javaList: JList[A]) (implicit a2bConversion: A => B): List[B] = javaList.toList map a2bConversion

Uso:

javaList2ScalaList[Integer, Int](someJavaList)

Esto se puede reutilizar para todas las listas, siempre que una conversión implícita del tipo contenido esté dentro del alcance.

(Y en caso de que tenga curiosidad, aquí está mi implementación para el mapa ...)

def javaMap2ScalaMap[A, B, C, D](javaMap: util.Map[A, B])(implicit a2cConversion: A => C, b2dConversion: B => D): Map[C, D] = javaMap.toMap map { case (a, b) => (a2cConversion(a), b2dConversion(b)) }


Has probado:

val javalist = collection.JavaConversions.asJavaList (y)

No estoy seguro de si necesita una conversión Int => Integer o Int => int aquí. ¿Puedes probarlo?

Actualización: los tiempos, son un cambio. Hoy obtendrá una advertencia obsoleta para ese código. Use en su lugar:

import scala.collection.JavaConverters._ val y = List (1) > y: List[Int] = List(1) val javalist = (y).asJava > javalist: java.util.List[Int] = [1]