Scala конвертирует List [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, но, насколько я могу судить, мне все равно понадобится дополнительный проход, чтобы вручную выполнить преобразование:

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

person Pandora Lee    schedule 09.08.2011    source источник


Ответы (6)


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

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
person paradigmatic    schedule 09.08.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)

person huynhjl    schedule 09.08.2011
comment
Это кажется наиболее правильным ответом. По-прежнему актуально с scala.collection.convert.decorateAsJava по состоянию на 2014 год с Scala 2.11.1. - person nadavwr; 15.10.2014

Ты пробовал:

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]
person user unknown    schedule 09.08.2011
comment
Похоже, что на самом деле он не преобразует базовый тип, по крайней мере, Idea дает мне ошибки типа. - person Antony Stubbs; 21.06.2013
comment
Я получил предупреждение только сегодня, но оно все еще работает - через 2 года после ответа: warning: there were 1 deprecation warnings; re-run with -deprecation for details javalist: java.util.List[Int] = [1]. Сегодня вы использовали бы JavaConverters. Обновляю свой ответ. - person user unknown; 21.06.2013

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

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 является частью стандартной библиотеки, использование в этом случае будет выглядеть так:

  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)) }
person jm0    schedule 07.06.2016

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

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

import scala.jdk.CollectionConverters._

List(1, 2, 3).map(Integer.valueOf).asJava
// java.util.List[Integer] = [1, 2, 3]
person Xavier Guihot    schedule 29.03.2019

Я пытался передать 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)
person ElBaulP    schedule 11.07.2018