Java 컬렉션을 Scala 컬렉션으로 변환


88

Stack Overflow 질문 관련된 Scala new HashSet (Collection) , Java 컬렉션 ( java.util.List말)을 Scala 컬렉션으로 List어떻게 변환 합니까?

실제로 Java API 호출 을를 반환하는 Spring 의을 Scala immutable 로 변환하려고합니다 . 예를 들면 다음과 같습니다.SimpleJdbcTemplatejava.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.Set기본적 감사로 사용할 수 있습니다 Predef.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

setscala.collection.immutable.Set[String]후입니다.

또한 지금 권장되는 것으로 보이는보다 명확한 방법 (JavaConverters 사용)에 대한 Ben James의 답변 을 참조하십시오 .


이제 호출이 필요하지 않게 JavaConversions만드는 암시가있는 것 같습니다 toSet.
Rajish

@Rajish 변환이 명시 적이면 더 낫다고 생각합니다 ( stackoverflow.com/questions/8301947/… 참조 )
krookedking

당신 말이 맞습니다. import scala.collection.JavaConverters._
Abhishek Sengupta

62

robinst의 답변 에서 보여준 JavaConversions보다 더 명확하게하려면 JavaConverters 를 사용할 수 있습니다.

import scala.collection.JavaConverters._
val l = new java.util.ArrayList[java.lang.String]
val s = l.asScala.toSet

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

업데이트 : JavaConversionsJavaConverters 가 더 이상 사용되지 않는다는 위의 설명 은 잘못된 것 같습니다. Scala 2.10에는 더 이상 사용되지 않는 속성이 있었기 때문에 가져올 때 사용 중단 경고가 발생했습니다. 따라서 여기서 대체 가져 오기는 별칭 일뿐입니다. 나는 여전히 그들을 선호하지만 IMHO로서 이름이 더 적절합니다.


JavaConversions 및 JavaConverters가 더 이상 사용되지 않는 이유는 무엇입니까? 현재 문서 2.11.8에서 둘 다 사용되지 않는 것으로 표시되지 않았으며 새롭고 선호되는 사용법을 나타내는 'decorateAll'또는 'wrapAll'에 대한 참조도 없습니다.
Joost den Boer

@JoostdenBoer Scala 2.10에서 더 이상 사용되지 않는 데코레이터 있는 것 같지만 Scala 2.11에서 다시 제거 된 것 같습니다.
stempler

14

Java와 Scala 컬렉션 간의 양방향 변환이있는 scalaj-collection 이라는 훌륭한 라이브러리를 탐색 할 수도 있습니다. 귀하의 경우 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

6
몇 년 후에 이것을 다시 살펴보면 Scala의 JavaConverters가 갈 길입니다.
Surya Suravarapu

4

시작 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에로
oxbow_lakes

1

이 문제를 해결하는 또 다른 간단한 방법 :

import collection.convert.wrapAll._
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.