Bir Java koleksiyonunu Scala koleksiyonuna dönüştürme


88

Stack Overflow sorusuyla ilgili olarak , yeni HashSet'in (Koleksiyon) Scala eşdeğeri, bir Java koleksiyonunu ( java.util.Listörneğin) bir Scala koleksiyonuna nasıl dönüştürebilirim List?

Aslında hiç bir Java API çağrısını dönüştürmek çalışıyorum Bahar adlı SimpleJdbcTemplate bir döner, java.util.List<T>bir Scala Immutable içine HashSet. Yani mesela:

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

Bu işe yarıyor gibi görünüyor. Eleştiri açığız!

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

Yanıtlar:


17

Son öneriniz işe yarıyor, ancak şunları kullanmaktan da kaçınabilirsiniz jcl.Buffer:

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

Not scala.collection.immutable.Setvarsayılan sayesinde temin edilir Predef.scala.


9
Tür bilgilerini saklamak istediğim yerde bu öneri çalışmıyor
oxbow_lakes

127

İleride referans olması için: Scala 2.8 ile şu şekilde yapılabilir:

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

setbundan scala.collection.immutable.Set[String]sonra.

Ayrıca , daha açık bir yol için (JavaConverters kullanarak) Ben James'in cevabına bakın, ki bu şimdi tavsiye edilmektedir.


Görünüşe göre şimdi aramayı gerekli JavaConversionskılan bazı sonuçlar var toSet.
Rajish

@Rajish Bence dönüşüm açıksa daha iyi (bkz. Stackoverflow.com/questions/8301947/… )
krookedking

haklısın, import scala.collection.JavaConverters._
Abhishek Sengupta

62

Eğer JavaConversions gösterildiği daha açık olmasını istiyorsanız robinst cevabı , sen JavaConverters kullanabilirsiniz:

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

25

JavaConversions ( robinst'in cevabı ) ve JavaConverters ( Ben James'in cevabı ) Scala 2.10 ile kullanımdan kaldırıldı .

JavaConversions yerine şunları kullanın:

import scala.collection.convert.wrapAll._

aleksandr_hramcov tarafından önerildiği gibi .

JavaConverters yerine şunları kullanın:

import scala.collection.convert.decorateAll._

Her ikisi için de dönüşümleri / dönüştürücüleri sırasıyla Java veya Scala'ya içe aktarma imkanı vardır, örneğin:

import scala.collection.convert.wrapAsScala._

Güncelleme: Yukarıdaki JavaConversions ve JavaConverters'ın kullanımdan kaldırıldığını belirten ifade yanlış gibi görünüyor. Scala 2.10'da bazı kullanımdan kaldırılmış özellikler vardı ve bunlar içe aktarılırken kullanımdan kaldırılma uyarılarına neden oldu. Dolayısıyla, buradaki alternatif içe aktarmalar yalnızca takma adlar gibi görünüyor. Halen tercih etsem de IMHO olarak isimler daha uygun.


Neden JavaConversions ve JavaConverters'ın kullanımdan kaldırıldığını söylüyorsunuz? Mevcut dokümantasyon 2.11.8'de her ikisi de kullanımdan kaldırılmış olarak işaretlenmemiştir ve ayrıca yeni ve tercih edilen kullanım olduğunu belirten 'decorateAll' veya 'wrapAll' referanslarına sahip değildir.
Joost den Boer

@JoostdenBoer Scala 2.10'da bazı onaylanmamış dekoratörler var gibi görünüyor, ancak Scala 2.11 ile tekrar kaldırılmış gibi görünüyorlar.
stempler

14

Ayrıca bu mükemmel kitaplığı keşfetmek isteyebilirsiniz: Java ve Scala koleksiyonları arasında iki yönlü dönüşüm sağlayan scalaj koleksiyonu. Sizin durumunuzda, bir java.util.List'i Scala List'e dönüştürmek için şunu yapabilirsiniz:

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

1
Bu kütüphane şimdiye kadarki en harika şey. Gerçekten gerçekten iyi çalışıyor.
Michael Neale

7
Birkaç yıl sonra bunu yeniden ziyaret eden Scala'nın JavaConverters'ı gitmek için yoldur.
Surya Suravarapu

5

Başlangıç Scala 2.13, paket, paketleri scala.jdk.CollectionConvertersdeğiştirir 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])

bu harika bir cevap ve sorunumu çözdü. İnternette bahsedilen yöntemlerin çoğu (örneğin) java.util.List [java.lang.Long] 'u scala.collection.immutable.List [java.lang.Long]' a dönüştürür. Dolayısıyla bu yöntem benim için onu scala.collection.immutable.List [scala.Long]
ajkl

2

Set'in parametreleştirilmesini sağlamak için toArray çağrısına tür bilgilerini ekleyebilirsiniz:

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

Koleksiyon paketi Scala 2.8 için büyük bir yeniden çalışmadan geçtiği ve scala.collection.jcl paketi ortadan kalktığı için bu tercih edilebilir olabilir.


1

Java koleksiyonunu bir diziye dönüştürebilir ve ardından bundan bir Scala listesi oluşturabilirsiniz:

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

2
Bu harika değil çünkü java.util.List bir Java API'sinden parametreleştirilmiş bir liste olarak geri geliyor (bu yüzden API'ye yaptığım çağrı bir java.util.List <String> veriyor) - bunu döndürmeye çalışıyorum değişmez bir
HashSet'e dönüşüyor

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.