Scala конвертирует List [Int] в java.util.List [java.lang.Integer] - PullRequest
35 голосов
/ 09 августа 2011

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

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

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

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

Ответы [ 6 ]

26 голосов
/ 09 августа 2011

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

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
22 голосов
/ 09 августа 2011

Поскольку базовым представлением 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 вместо)

4 голосов
/ 09 августа 2011

Вы пробовали:

val javalist = collection.JavaConversions.asJavaList (y)

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

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

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

val javalist = (y).asJava
> javalist: java.util.List[Int] = [1]
2 голосов
/ 08 июня 2016

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

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)) }
0 голосов
/ 30 марта 2019

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

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

import scala.jdk.CollectionConverters._

List(1, 2, 3).map(Integer.valueOf).asJava
// java.util.List[Integer] = [1, 2, 3]
0 голосов
/ 11 июля 2018

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

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