Jak uzyskać listę Scala z listy Java?

133

Mam interfejs API Java, który zwraca listę, taką jak:

public List<?> getByXPath(String xpathExpr)

Używam poniższego kodu scala:

val lst = node.getByXPath(xpath)

Teraz, jeśli spróbuję cukru składniowego Scala, takiego jak:

lst.foreach{ node => ... }

to nie działa. Wyskakuje mi błąd:

value foreach is not a member of java.util.List[?0]

Wygląda na to, że muszę przekonwertować listę Java do listy Scala. Jak to zrobić w powyższym kontekście?

as
źródło
2
możliwy duplikat kolekcji Converting Java do kolekcji Scala
Kim Stebel
@Kim: Nie jestem pewien, czy należy zamknąć to jako duplikat tego konkretnego pytania - to konkretne pytanie dotyczy Scali 2.7, a pakiet scala.collection.jcl nie istnieje już w Scali 2.8 i 2.9.
Ken Bloom,

Odpowiedzi:

177

EDYCJA: Zauważ, że jest to przestarzałe od wersji 2.12.0. Użyj JavaConverterszamiast tego. (komentarz @Yaroslav)

Od Scala 2.8 ta konwersja jest teraz wbudowana w język przy użyciu:

import scala.collection.JavaConversions._

...

lst.toList.foreach{ node =>   .... }

Pracuje. asScalanie działał

as
źródło
13
W wersji 2.10.4 musiałem zaimportować scala.collection.JavaConverters._ w przeciwnym razie otrzymałem „wartość asScala nie jest członkiem java.util.List [String]”
dranxo
11
JavaConversionssą przestarzałe od 2.12.0. Użyj JavaConverterszamiast tego.
Jarosław
4
W przypadku wersji 2.13.x potrzebujesz import scala.jdk.CollectionConverters._ scala-lang.org/api/2.13.x/scala/jdk/CollectionConverters$.html
Nikolaos Georgiou
92

Do tego celu służy przydatny obiekt Scala - scala.collection.JavaConverters

Możesz wykonać import, a asScalanastępnie w następujący sposób:

import scala.collection.JavaConverters._

val lst = node.getByXPath(xpath).asScala
lst.foreach{ node =>   .... }

To powinno dać ci Bufferreprezentację Scali, która pozwoli ci to osiągnąć foreach.

montreal.eric
źródło
7
JavaConverters powinny być preferowane przed JavaConversions, ponieważ sprawia, że ​​konwersja jest jawna (i unika przypadkowych konwersji, które mogą być mylące). (To znaczy, jest to poprawna odpowiedź)
Mark
od wersji 2.13 ta klasa również jest przestarzała. Zamiast tego użyj scala.jdk.CollectionConverters.
dev-null
9

Szukałem odpowiedzi napisanej w Javie i zaskakująco nie mogłem znaleźć tutaj czystych rozwiązań. Po jakimś czasie udało mi się to rozgryźć, więc postanowiłem dodać to tutaj na wypadek, gdyby ktoś inny szukał implementacji Javy (myślę, że to też działa w Scali?):

JavaConversions.asScalaBuffer(myJavaList).toList()
Źródło
źródło
9

Jeśli musisz przekonwertować Javę List<ClassA>na Scalę List[ClassB], musisz wykonać następujące czynności:

1) Dodaj

import scala.collection.JavaConverters._

2) Użyj metod asScala, toLista następniemap

List <ClassA> javaList = ...
var scalaList[ClassB] = javaList.asScala.toList.map(x => new ClassB(x))

3) Dodaj następujący kod do ClassBkonstruktora, który otrzymuje ClassAjako parametr:

case class ClassB () {
   def this (classA: ClassA) {
      this (new ClassB (classA.getAttr1, ..., classA.getAttrN))
   }
}
Leandro carrasco
źródło
6

Od wersji 2.8.1 scala używaj JavaConverters._ do konwertowania kolekcji scala i Java przy użyciu metod asScala i asJava.

import scala.collection.JavaConverters._

javalist.asScala

scalaSeq.asJava

zobacz stronę z dokumentacją Scala relacji konwersji

user1553728
źródło
6

Skrót do konwersji listy java na listę scala

import scala.collection.JavaConverters._

myjavaList.asScala.toList

Xing-Wei Lin
źródło