การแปลงคอลเลกชัน Java เป็นคอลเลกชัน Scala


88

ที่เกี่ยวข้องกับคำถาม Stack Overflow Scala เทียบเท่ากับ HashSet (Collection)ใหม่ฉันจะแปลงคอลเลกชัน Java ( java.util.Listพูด) เป็นคอลเล็กชัน Scala ได้Listอย่างไร

ฉันกำลังจริงพยายามที่จะแปลงเรียก API Java เพื่อฤดูใบไม้ผลิ SimpleJdbcTemplateซึ่งส่งกลับลงไปในไม่เปลี่ยนรูปสกาล่าjava.util.List<T> HashSetตัวอย่างเช่น:

val l: java.util.List[String] = javaApi.query( ... )
val s: HashSet[String] = //make a set from l

ดูเหมือนว่าจะได้ผล ยินดีรับคำติชม!

import scala.collection.immutable.Set
import scala.collection.jcl.Buffer 
val s: scala.collection.Set[String] =
                      Set(Buffer(javaApi.query( ... ) ) : _ *)

คำตอบ:


17

คำแนะนำสุดท้ายของคุณใช้ได้ผล แต่คุณสามารถหลีกเลี่ยงการใช้jcl.Buffer:

Set(javaApi.query(...).toArray: _*)

โปรดทราบว่าจะทำใช้ได้โดยขอบคุณค่าเริ่มต้นscala.collection.immutable.SetPredef.scala


9
คำแนะนำนี้ใช้ไม่ได้ในที่ที่ฉันต้องการเก็บข้อมูลประเภท
oxbow_lakes

127

สำหรับการอ้างอิงในอนาคต: ด้วย Scala 2.8 สามารถทำได้ดังนี้:

import scala.collection.JavaConversions._
val list = new java.util.ArrayList[String]()
list.add("test")
val set = list.toSet

setเป็นscala.collection.immutable.Set[String]หลังจากนี้

ดูคำตอบของ Ben Jamesสำหรับวิธีที่ชัดเจนยิ่งขึ้น (โดยใช้ JavaConverters) ซึ่งดูเหมือนว่าจะแนะนำในตอนนี้


ดูเหมือนว่าตอนนี้JavaConversionsจะมีนัยบางอย่างที่ทำให้การtoSetโทรไม่จำเป็น
Rajish

@Rajish ฉันคิดว่ามันจะดีกว่าถ้าการแปลงเป็นแบบชัดแจ้ง (ดูstackoverflow.com/questions/8301947/… )
krookedking

คุณพูดถูกควรใช้ import scala.collection.JavaConverters._
Abhishek Sengupta


25

JavaConversions ( คำตอบของ robinst ) และJavaConverters ( คำตอบของ Ben James ) เลิกใช้งานกับScala 2.10แล้ว

แทนที่จะใช้JavaConversionsใช้:

import scala.collection.convert.wrapAll._

ตามที่แนะนำโดยaleksandr_hramcov

แทนที่จะใช้JavaConvertersใช้:

import scala.collection.convert.decorateAll._

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

import scala.collection.convert.wrapAsScala._

อัปเดต: ข้อความข้างต้นที่ว่าJavaConversionsและJavaConvertersถูกเลิกใช้ดูเหมือนจะไม่ถูกต้อง มีคุณสมบัติบางอย่างที่เลิกใช้แล้วใน Scala 2.10 ซึ่งส่งผลให้มีคำเตือนการเลิกใช้งานเมื่อนำเข้า ดังนั้นการนำเข้าทางเลือกที่นี่ดูเหมือนจะเป็นเพียงนามแฝงเท่านั้น แม้ว่าฉันจะยังชอบพวกเขาอยู่ก็ตามเนื่องจาก IMHO ชื่อนั้นเหมาะสมกว่า


ทำไมคุณถึงบอกว่า JavaConversions และ JavaConverters เลิกใช้งานแล้ว? ในเอกสารปัจจุบัน 2.11.8 ทั้งสองไม่ได้ถูกทำเครื่องหมายว่าเลิกใช้งานแล้วและยังไม่มีการอ้างอิงถึง 'decorationAll' หรือ 'wrapAll' ที่ระบุว่าเป็นการใช้งานใหม่และเป็นที่ต้องการ
Joost den Boer

@JoostdenBoer ดูเหมือนจะมีบางส่วนตกแต่งเลิกก็มีใน Scala 2.10 แม้ว่าพวกเขาดูเหมือนจะได้ถูกลบออกอีกครั้งกับ Scala 2.11
stempler

14

คุณอาจต้องการสำรวจไลบรารีที่ยอดเยี่ยมนี้: scalaj-collectionที่มีการแปลงสองทางระหว่างคอลเลกชัน Java และ Scala ในกรณีของคุณในการแปลง java.util.List เป็น Scala List คุณสามารถทำได้:

val list = new java.util.ArrayList[java.lang.String]
list.add("A")
list.add("B")
list.asScala

1
ห้องสมุดเป็นสิ่งที่ยิ่งใหญ่ที่สุดที่เคยมีมา ใช้งานได้ดีจริงๆ
Michael Neale

7
การทบทวนสิ่งนี้หลังจากผ่านไปสองสามปี JavaConverters ของ Scala คือหนทางที่จะไป
Surya Suravarapu

5

เริ่มต้นScala 2.13แพ็คเกจscala.jdk.CollectionConvertersจะแทนที่แพ็คเกจscala.collection.JavaConverters/JavaConversions._:

import scala.jdk.CollectionConverters._

// val javaList: java.util.List[String] = java.util.Arrays.asList("one","two","three")
javaList.asScala
// collection.mutable.Buffer[String] = Buffer("one", "two", "three")
javaList.asScala.toSet
// collection.immutable.Set[String] = Set("one", "two", "three")

3
val array = java.util.Arrays.asList("one","two","three").toArray

val list = array.toList.map(_.asInstanceOf[String])

นี่เป็นคำตอบที่ดีและช่วยแก้ปัญหาของฉันได้ วิธีการส่วนใหญ่ที่กล่าวถึงบนอินเทอร์เน็ตเพียงแค่แปลง (เช่น) java.util.List [java.lang.Long] เป็น scala.collection.immutable.List [java.lang.Long] ดังนั้นวิธีนี้ใช้ได้ผลสำหรับฉันในการแปลงเป็น scala.collection.immutable.List [scala.Long]
ajkl

2

คุณสามารถเพิ่มข้อมูลประเภทในการเรียก toArray เพื่อทำให้ Set เป็นพารามิเตอร์:

 val s = Set(javaApi.query(....).toArray(new Array[String](0)) : _*)

สิ่งนี้อาจดีกว่าเนื่องจากแพ็คเกจคอลเลกชันกำลังผ่านการปรับปรุงครั้งใหญ่สำหรับ Scala 2.8 และแพ็คเกจ scala.collection.jcl กำลังจะหายไป


1

คุณสามารถแปลงคอลเลกชัน Java เป็นอาร์เรย์จากนั้นสร้างรายการ Scala จากสิ่งนั้น:

val array = java.util.Arrays.asList("one","two","three").toArray
val list = List.fromArray(array)

2
สิ่งนี้ไม่ดีเพราะ java.util.List ของฉันกำลังกลับมาจาก Java API เป็นรายการพารามิเตอร์ (ดังนั้นการเรียก API ของฉันจะให้ java.util.List <String>) - ฉันกำลังพยายามเปลี่ยนสิ่งนี้ เป็น HashSet ที่ไม่เปลี่ยนรูป scala
oxbow_lakes

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