จะแปลง scala.List เป็น java.util.List ได้อย่างไร?


คำตอบ:


69

Scala List และ Java List เป็นสัตว์ร้ายสองชนิดที่แตกต่างกันเนื่องจากในอดีตไม่เปลี่ยนรูปและตัวหลังนั้นไม่แน่นอน ดังนั้นก่อนอื่นคุณต้องแปลงรายการ Scala เป็นคอลเล็กชันที่ไม่แน่นอน

บน Scala 2.7:

import scala.collection.jcl.Conversions.unconvertList
import scala.collection.jcl.ArrayList
unconvertList(new ArrayList ++ List(1,2,3))

ตั้งแต่ Scala 2.8 เป็นต้นไป:

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
asList(ListBuffer(List(1,2,3): _*))
val x: java.util.List[Int] = ListBuffer(List(1,2,3): _*)

อย่างไรก็ตามasListในตัวอย่างนั้นไม่จำเป็นหากประเภทที่คาดไว้คือ Java Listเนื่องจากการแปลงเป็นนัยดังที่แสดงโดยบรรทัดสุดท้าย


val x: java.util.List [Int] ยังคงไม่เปลี่ยนรูป เพียงแค่ลองใช้ Java เป็น x.add (บางอย่าง) - มันจะทำให้เกิดข้อผิดพลาด
Vitamon

1
@Vitamon มันไม่ได้ทำให้เกิดข้อผิดพลาดใด ๆ สำหรับฉัน - ฉันเพิ่งทดสอบเพื่อยืนยัน
Daniel C. Sobral

4
เลิกใช้งานscala.collection.JavaConvertersตั้งแต่ 2.12
เป็นต้น

สำหรับ 2.12.1 เมื่อทำซ้ำรายการ Java ทันทีด้วย Scala for loop ฉันโชคดีกว่ากับ asScalaBuffer () ในแพ็คเกจJavaConverters
Sarah Messer

165

ไม่แน่ใจว่าทำไมถึงไม่เคยพูดถึงมาก่อน แต่ฉันคิดว่าวิธีที่ง่ายที่สุดคือการเรียกใช้asJavaเมธอดมัณฑนากรของJavaConvertersโดยตรงในรายการ Scala:

scala> val scalaList = List(1,2,3)
scalaList: List[Int] = List(1, 2, 3)

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> scalaList.asJava
res11: java.util.List[Int] = [1, 2, 3]

6
นอกจากนี้ยังต้องการให้คุณมีความชัดเจนมากกว่าที่จะขึ้นอยู่กับเวทมนตร์โดยนัยบางอย่างที่บางครั้งอาจไม่ต้องการ
Kamil Lelonek

สิ่งนี้ทำให้เกิดปัญหาหากจัดลำดับรายการเพื่อใช้ในโค้ด Java ในภายหลัง ... ผลลัพธ์ใน ClassNotFoundException: scala.collection.convert.Wrappers Arrays.asList (foo: _ *) ใช้งานได้ในกรณีนี้
Mohan

ฉันมาที่หน้านี้ทุกครั้งที่ต้องใช้ Java ใน Scala น่าเสียดายที่ไม่มีความคิดที่จะแนะนำคำแนะนำการนำเข้าที่เหมาะสมสำหรับ ".asJava" ให้ฉัน ((
mulya

24

เพื่อสรุปคำตอบก่อนหน้านี้

สมมติว่าเรามีสิ่งต่อไปนี้List:

scala> val scalaList = List(1,2,3)
scalaList: List[Int] = List(1, 2, 3)

หากคุณต้องการชัดเจนและบอกสิ่งที่คุณต้องการแปลง:

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> scalaList.asJava
res11: java.util.List[Int] = [1, 2, 3]

หากคุณไม่ต้องการให้ผู้ร่วมควบคุมการแปลงและปล่อยให้คอมไพเลอร์ทำงานให้คุณโดยปริยาย :

scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._

scala> val javaList: java.util.List[Int] = scalaList
javaList: java.util.List[Int] = [1, 2, 3]

ขึ้นอยู่กับว่าคุณต้องการควบคุมโค้ดของคุณอย่างไร


8

เริ่มต้นScala 2.13แพคเกจscala.jdk.CollectionConvertersมีให้asJavaผ่านทางแมงดาSeqและแทนที่แพ็คเกจscala.collection.JavaConverters/JavaConversions:

import scala.jdk.CollectionConverters._

// val scalaList: List[Int] = List(1, 2, 3)
scalaList.asJava
// java.util.List[Int] = [1, 2, 3]

7

แม้ว่าฉันจะตอบคำถามเก่า ๆ แต่คำแนะนำส่วนใหญ่เลิกใช้แล้ว

import scala.collection.JavaConversions.seqAsJavaList

val myList = List("a", "b", "c")
val myListAsJavaList = seqAsJavaList[String](myList)

object JavaConversions in package collection is deprecated (since 2.12.0): use JavaConverters
Prayagupd

5

ปรับปรุง

ด้วย scala 2.9.2:

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
val x: java.util.List[Int] = ListBuffer( List( 1, 2, 3 ): _* )

ผลลัพธ์

[1, 2, 3]

1

สำหรับการเรียกใช้ครั้งเดียวการทำด้วยมืออาจเป็นวิธีที่ง่ายที่สุด:

val slist = List (1, 2, 3, 4)          
val jl = new java.util.ArrayList [Integer] (slist.size)
slist.foreach (jl.add (_))   

ฉันไม่ได้วัดประสิทธิภาพ


0

เพียงทำตามที่เสนอไว้ข้างต้นจะสร้างรายการที่ไม่เปลี่ยนรูปแม้แต่ในฝั่ง Java ทางออกเดียวที่ฉันพบคือ:

def toJList[T](l:List[T]):util.List[T] = {
  val a = new util.ArrayList[T]
  l.map(a.add(_))
  a
 }

0

เนื่องจาก Scala 2.12.0 JavaConversions เลิกใช้งานแล้ว

ดังนั้นทางออกที่ง่ายที่สุดสำหรับฉันคือ:

java.util.Arrays.asList("a","b","c")

1
คำตอบนี้ไม่ได้อธิบายวิธีการใช้สิ่งนี้เพื่อแปลงรายการ scala เป็นรายการ java Arrays.asList อาจเป็นปัญหาได้เช่นกันเนื่องจากส่งคืน Arrays.ArrayList ซึ่งไม่ใช่รายการที่ปรับขนาดได้ซึ่งอาจทำให้เกิดข้อผิดพลาดที่ไม่คาดคิดหากคุณคิดว่าคุณมี util.ArrayList
puhlen

1
การเลิกใช้งานเป็นความจริงมีimport scala.collection.JavaConverters._สำหรับ 2.12.4
ภาวนา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.