Java与Scala的容器转换
参考:
- scala.collection.JavaConverters
- scala.mutable.Buffer
- scala基础——Java和Scala容器的转换
- Scala Iterator(迭代器)
- scala 学习(三)——Array和ArrayBuffer
如果想要在scala中将Java和Scala容器相互转化,首先要导入相应包:
import scala.collection.JavaConverters._
根据官方文档:
一系列装饰器方法使用
asScala
和asJava
将Java和Scala的集合互相转换。以下的转化可以通过
asJava
、asScala
进行:
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时需要使用特殊命名的方法:
asJavaCollection
、asJavaEnumeration
、asJavaDictionary
:
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<Element>、 Collection<Element>、 List<Element>、 RandomAccess这些Java接口,而且Elements
的构造方法有Elements()
、Elements(int initialCapacity)
、Elements(Collection<Element> elements)
、Elements(List<Element> 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)
这样,就可以对其使用foreach
、map
等Scala 的容器方法:
val doc:Document= Jsoup.connect("https://www.......").get();
val ps=doc select "p"
ps foreach (Console println _ )