【发布时间】:2013-01-14 22:31:48
【问题描述】:
下面的 Scala 类使用 JDOM 解析文件并将文件中的值填充到 Scala 不可变 Map 中。在 Map 上使用 + 运算符似乎没有任何效果,因为 Map 始终为零。
import java.io.File
import org.jsoup.nodes.Document
import org.jsoup.Jsoup
import org.jsoup.select.Elements
import org.jsoup.nodes.Element
import scala.collection.immutable.TreeMap
class JdkElementDetail() {
var fileLocation: String = _
def this(fileLocation: String) = {
this()
this.fileLocation = fileLocation;
}
def parseFile : Map[String , String] = {
val jdkElementsMap: Map[String, String] = new TreeMap[String , String];
val input: File = new File(fileLocation);
val doc: Document = Jsoup.parse(input, "UTF-8", "http://example.com/");
val e: Elements = doc.getElementsByAttribute("href");
val href: java.util.Iterator[Element] = e.iterator();
while (href.hasNext()) {
var objectName = href.next();
var hrefValue = objectName.attr("href");
var name = objectName.text();
jdkElementsMap + name -> hrefValue
println("size is "+jdkElementsMap.size)
}
jdkElementsMap
}
}
println("size is "+jdkElementsMap.size) always prints "size is 0"
为什么大小总是零,我没有正确添加到地图吗?
解决此问题的唯一方法是将 jdkElementsMap 转换为 var 然后使用以下内容吗?
jdkElementsMap += name -> hrefValue
这里删除while循环是我更新的对象:
package com.parse
import java.io.File
import org.jsoup.nodes.Document
import org.jsoup.Jsoup
import org.jsoup.select.Elements
import org.jsoup.nodes.Element
import scala.collection.immutable.TreeMap
import scala.collection.JavaConverters._
class JdkElementDetail() {
var fileLocation: String = _
def this(fileLocation: String) = {
this()
this.fileLocation = fileLocation;
}
def parseFile : Map[String , String] = {
var jdkElementsMap: Map[String, String] = new TreeMap[String , String];
val input: File = new File(fileLocation);
val doc: Document = Jsoup.parse(input, "UTF-8", "http://example.com/");
val elements: Elements = doc.getElementsByAttribute("href");
val elementsScalaIterator = elements.iterator().asScala
elementsScalaIterator.foreach {
keyVal => {
var hrefValue = keyVal.attr("href");
var name = keyVal.text();
println("size is "+jdkElementsMap.size)
jdkElementsMap += name -> hrefValue
}
}
jdkElementsMap
}
}
【问题讨论】:
-
当
x是不可变对象时,x + z对x没有影响;如果它确实有效果,它就不会是不可变的!使用返回值,这是一个 new 不可变映射。 -
嗯,不是“唯一”的方式,但它会起作用。一种选择是递归;最好以 TCO 友好的方式编写并使用
@tailrec进行验证。我相信有人会用一种巧妙的方法将循环(hasNext/next)包装到地图中(即for .. yield)或提及一些关于 monad 的事情:D -
我会看看stackoverflow.com/a/2709031/166390(提到JavaConversions)和stackoverflow.com/questions/8301947/…(较新的JavaConverters)——然后你可以用摆脱那个icky Java迭代器icky 程序循环并使用简单的地图操作,为什么要提出比其他选项“不那么可怕”的东西:D
标签: scala