Konvertieren einer Java-Sammlung in eine Scala-Sammlung


87

Bezogen auf Stack - Überlauf Frage Scala Äquivalent neuen HashSet (Collection) , wie konvertiere ich eine Java - Sammlung ( java.util.Listsagen wir) in eine Scala Sammlung List?

Ich versuche tatsächlich, einen Java-API-Aufruf in Spring's SimpleJdbcTemplate , der a zurückgibt java.util.List<T>, in eine unveränderliche Scala umzuwandeln HashSet. Also zum Beispiel:

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

Das scheint zu funktionieren. Kritik ist willkommen!

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

Antworten:


17

Ihr letzter Vorschlag funktioniert, aber Sie können auch vermeiden, Folgendes zu verwenden jcl.Buffer:

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

Beachten Sie, dass dies scala.collection.immutable.Setdank standardmäßig verfügbar ist Predef.scala.


9
Dieser Vorschlag funktioniert nicht, wenn ich die
Typinformationen

126

Zum späteren Nachschlagen: Mit Scala 2.8 könnte dies folgendermaßen geschehen:

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

setist ein scala.collection.immutable.Set[String]danach.

Siehe auch die Antwort von Ben James für einen expliziteren Weg (mit JavaConverters), der jetzt empfohlen zu werden scheint.


7
@oxbow_lakes Ich denke, es ist Zeit, diese Antwort als die akzeptierte zu markieren.
Nikita Volkov

Sieht so aus, als hätte es jetzt JavaConversionseinige Implikationen, die den toSetAnruf nicht notwendig machen.
Rajish

@ Rajish Ich denke, es ist besser, wenn die Konvertierung explizit ist (siehe stackoverflow.com/questions/8301947/… )
krookedking

Sie haben Recht, es ist besser, import scala.collection.JavaConverters._
Abhishek Sengupta

62

Wenn Sie expliziter sein möchten als die in der Antwort von robinst gezeigten JavaConversions , können Sie JavaConverters verwenden:

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

25

JavaConversions ( Antwort von robinst ) und JavaConverters ( Antwort von Ben James ) sind mit Scala 2.10 veraltet .

Verwenden Sie anstelle von JavaConversions :

import scala.collection.convert.wrapAll._

wie von aleksandr_hramcov vorgeschlagen .

Verwenden Sie anstelle von JavaConverters :

import scala.collection.convert.decorateAll._

Für beide gibt es auch die Möglichkeit, nur die Konvertierungen / Konverter nach Java bzw. Scala zu importieren, zB:

import scala.collection.convert.wrapAsScala._

Update: Die obige Aussage, dass JavaConversions und JavaConverters veraltet waren, scheint falsch zu sein. In Scala 2.10 gab es einige veraltete Eigenschaften, die beim Import zu veralteten Warnungen führten. Die alternativen Importe hier scheinen also nur Aliase zu sein. Obwohl ich sie immer noch bevorzuge, sind die Namen meiner Meinung nach angemessener.


Warum sind JavaConversions und JavaConverters Ihrer Meinung nach veraltet? In der aktuellen Dokumentation 2.11.8 sind beide nicht als veraltet gekennzeichnet und sie enthalten auch keinen Verweis auf 'decorateAll' oder 'wrapAll', der angibt, dass dies die neue und bevorzugte Verwendung ist.
Joost den Boer

@JoostdenBoer Es scheint, dass es in Scala 2.10 einige veraltete Dekorateure gab , obwohl sie mit Scala 2.11 wieder entfernt worden zu sein scheinen.
Stempler

14

Vielleicht möchten Sie auch diese hervorragende Bibliothek erkunden: Scalaj-Sammlung mit bidirektionaler Konvertierung zwischen Java- und Scala-Sammlungen. In Ihrem Fall können Sie Folgendes tun, um eine java.util.List in eine Scala-Liste zu konvertieren:

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

1
Diese Bibliothek ist das Beste, was es je gab. Funktioniert wirklich sehr gut.
Michael Neale

6
Scalas JavaConverters ist der richtige Weg, um dies nach einigen Jahren noch einmal zu überprüfen.
Surya Suravarapu

4

Beim Starten ersetzt das Scala 2.13Paket scala.jdk.CollectionConvertersdie Pakete 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])

Dies ist eine großartige Antwort und hat mein Problem gelöst. Die meisten der im Internet erwähnten Methoden konvertieren einfach die (z. B.) java.util.List [java.lang.Long] in scala.collection.immutable.List [java.lang.Long]. Also hat diese Methode für mich funktioniert, um sie in scala.collection.immutable.List [scala.Long] zu konvertieren
ajkl

2

Sie können die Typinformationen im toArray-Aufruf hinzufügen, damit das Set parametrisiert wird:

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

Dies könnte vorteilhaft sein , wenn die Packung Sammlungen wird durch eine große Nacharbeit für Scala gehen 2.8 und das scala.collection.jcl Paket weggeht


1

Sie können die Java-Sammlung in ein Array konvertieren und daraus eine Scala-Liste erstellen:

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

2
Dies ist nicht besonders gut, da meine java.util.List als parametrisierte Liste aus einer Java-API zurückkommt (mein Aufruf der API ergibt also eine java.util.List <String>). Ich versuche, dies zu ändern in eine Scala unveränderliche HashSet
oxbow_lakes

1

Ein weiterer einfacher Weg, um dieses Problem zu lösen:

import collection.convert.wrapAll._
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.