Подтвердить что ты не робот

Scala конвертировать список [Int] в java.util.List [java.lang.Integer]

Есть ли в Scala способ конвертировать List[Int] в java.util.List[java.lang.Integer]?

Я взаимодействую с Java (Thrift).

JavaConversions поддерживает List --> java.util.List, и между Int --> java.lang.Integer существуют Int --> java.lang.Integer, но из того, что я могу сказать, мне все равно понадобится дополнительный проход, чтобы вручную выполнить преобразование:

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

Ответ 1

Очевидно, вам нужны оба преобразования. Однако вы можете сгруппировать их в одно неявное преобразование:

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

Пример:

scala> def sizeOf( lst: java.util.List[java.lang.Integer] ) = lst.size

scala> sizeOf( List(1,2,3) )
res5: Int = 3

Ответ 2

Поскольку базовое представление Int - это Integer, вы можете напрямую передать его в java.util.List[java.lang.Integer]. Это сэкономит вам операцию O (n) и некоторые неявные вещи.

import collection.JavaConversions._

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

Затем вы можете использовать из Java следующим образом:

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

Обратите внимание, что на 2.9.0 я получаю предупреждение об отказе от asList (вместо этого используйте seqAsJavaList)

Ответ 3

Вы пытались:

val javalist = collection.JavaConversions.asJavaList (y)

Я не уверен, нужно ли вам преобразовать Int = > Integer или Int = > int здесь. Вы можете попробовать?

Update: Время, они меняются. Сегодня вы получите устаревшее предупреждение для этого кода. Вместо этого используйте

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

val javalist = (y).asJava
> javalist: java.util.List[Int] = [1]

Ответ 4

Это не имеет неявного на самом верхнем уровне, но мне нравится этот общий подход и реализовал его для нескольких типов коллекций (List, Map).

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

Поскольку неявное преобразование из Int в Integer является частью стандартного lib, использование в этом случае будет выглядеть следующим образом:

  scalaList2JavaList[Int, Integer](someScalaList)

В другом направлении!

(поскольку у меня есть все эти возможности, поскольку они были моими исходными реализациями...)

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

Использование:

  javaList2ScalaList[Integer, Int](someJavaList)

Затем он может быть повторно использован для всех списков, если неявное преобразование содержащегося в нем типа находится в области видимости.

(И если вам интересно, вот моя реализация для карты...)

  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)) }

Ответ 5

Я пытался передать Map[String, Double] в метод Java. Но проблема заключалась в том, что JavaConversions конвертирует Map в java Map, но оставляет scala Double как есть, а не конвертирует его в java.lang.Double. После нескольких часов поисков я нашел [ответ Альваро Карраско] (fooobar.com/questions/6152749/...), это так же просто, как сделать:

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

После этого javaMap является Map[String, java.lang.Double]. Затем вы можете передать это в функцию Java, которая ожидает Map<String, Double> и благодаря неявным преобразованиям карта Scala будет преобразована в java.util.Map

В вашем случае было бы то же самое, но с Int.box:

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

Ответ 6

Начиная с Scala 2.13, стандартная библиотека включает scala.jdk.CollectionConverters которая предоставляет неявные преобразования коллекций из Scala в Java.

Что мы можем объединить с java.lang.Integer::valueOf для преобразования Scala Int в Java Integer:

import scala.jdk.CollectionConverters._

List(1, 2, 3).map(Integer.valueOf).asJava
// java.util.List[Integer] = [1, 2, 3]