Java与Scala的容器转换

参考:

  • scala.collection.JavaConverters
  • scala.mutable.Buffer
  • scala基础——Java和Scala容器的转换
  • Scala Iterator(迭代器)
  • scala 学习(三)——Array和ArrayBuffer

如果想要在scala中将Java和Scala容器相互转化,首先要导入相应包:

import scala.collection.JavaConverters._

根据官方文档:

一系列装饰器方法使用asScalaasJava将Java和Scala的集合互相转换。

以下的转化可以通过asJavaasScala进行:

scala.collection.Iterable <=> java.lang.Iterable
scala.collection.Iterator <=> java.util.Iterator
scala.collection.mutable.Buffer <=> java.util.List
scala.collection.mutable.Set <=> java.util.Set
scala.collection.mutable.Map <=> java.util.Map
scala.collection.mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap

在上面所有转化情况中,如果将原类型转为目标类型,然后再转回来,将会得到原先的目标对象,比如:

   import scala.collection.JavaConverters._

   val sl = new scala.collection.mutable.ListBuffer[Int]
   val jl : java.util.List[Int] = sl.asJava
   val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala //转回
   assert(sl eq sl2)  //True

以下转化和上面类似,但是从Scala转Java时需要使用特殊命名的方法:asJavaCollectionasJavaEnumerationasJavaDictionary

scala.collection.Iterable <=> java.util.Collection
scala.collection.Iterator <=> java.util.Enumeration
scala.collection.mutable.Map <=> java.util.Dictionary

另外,以下转换只能使用asJava从Scala转Java:

scala.collection.Seq => java.util.List
scala.collection.mutable.Seq => java.util.List
scala.collection.Set => java.util.Set
scala.collection.Map => java.util.Map

例如,构建一个包装Jsoup的Elements类型的类:

class JsoupElementsWrapper(jElements:java.util.List[Element]) 
  extends Elements(jElements){
    private val elements:Buffer[Element]=jElements.asScala
}
object JsoupElementsWrapper{
    implicit def elementsToWrapper(e:Elements)=new JsoupElementsWrapper(e)
}

在查阅Jsoup的API文档后,发现Elements具有Serializable、 Cloneable、 Iterable、 Collection、 List、 RandomAccess这些Java接口,而且Elements的构造方法有Elements​()Elements​(int initialCapacity)Elements​(Collection elements)Elements​(List elements)Elements​(Element... elements)

则类JsoupElementsWrapper继承Elements类时,类参数类型可以选为java..util.List[Element],然后传给Elements类的构造参数:

class JsoupElementsWrapper(jElements:java.util.List[Element]) 
  extends Elements(jElements){
    ....

在内部创建一个Scala的Buffer方法,因为我们已经知道scala.collection.mutable.Buffer <=> java.util.List,此时只要对java.util.List类型参数jElements调用asScala即可:

private val elements:Buffer[Element]=jElements.asScala

在这里会调用隐式转化方法implicit def asScalaBufferConverter[A](l: List[A]): AsScala[Buffer[A]]

jElements.asScala
=>
asScalaBufferConverter(jElements).asScala

接下来,还需要一个将Elements转为JsoupElementsWrapper的隐式方法:

implicit def elementsToWrapper(e:Elements)=new JsoupElementsWrapper(e)

这样,就可以对其使用foreachmap等Scala 的容器方法:

val doc:Document= Jsoup.connect("https://www.......").get();
val ps=doc select "p"
ps foreach (Console println _ )

你可能感兴趣的:(Java与Scala的容器转换)