18

请检查这个

import scala.collection.mutable.LinkedList

var l = new LinkedList[String]

l append LinkedList("abc", "asd")

println(l)
// prints 
// LinkedList()

import scala.collection.mutable.LinkedList

var l = new LinkedList[String]

l = LinkedList("x")
l append LinkedList("abc", "asd")

println(l)
// prints 
// LinkedList(x, abc, asd)

为什么第二个代码片段有效,但第一个无效?这是在 Scala 2.10 上

4

2 回答 2

24

文档说If this is empty then it does nothing and returns that. Otherwise, appends that to this.。这正是你观察到的。如果你真的需要一个可变列表,我建议你改用scala.collection.mutable.ListBuffer它,你可以这样做

val lb = new ListBuffer[Int]

scala> lb += 1
res14: lb.type = ListBuffer(1)

scala> lb
res15: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1)

scala> lb ++= Seq(1,2,3)
res17: lb.type = ListBuffer(1, 1, 2, 3, 1, 2, 3)

scala> lb
res18: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 1, 2, 3, 1, 2, 3)
于 2013-04-02T10:40:04.643 回答
3

据我了解,它与列表中的 First/Last ( Nil) 元素有关(如果列表为空Nil,则同时是第一个和最后一个元素)。

LinkedList(仍然)遵循“原始魅力”的策略。因此,它不会尝试将新数据添加/追加到/之后Nil,可能会产生如下结果:{Nil, newElement}。(毕竟Nil应该是最后一个元素)

当然它可以检查if列表是否为空,然后放在addingList开头和Nil结尾。但这将是“太聪明了”,我猜。

但是,无论如何append()都会返回“预期”的结果,如下所示:

val addingList = new LinkedList[String]("a", "b")
val result = emptyList append addingList

result = {"a", "b"}.在这种情况下,它会返回 'addingList' 本身,和/但不会更改初始列表。

如果我们尝试将 newElement 分配给nextref:

   emptyList.next = LinkedList("whatever")

结果,我们将 emtyList 更改为:

 LinkedList(null, whatever)

它将第一个元素创建为 null,因为我们已经使用next()分配新/下一个元素给它。所以它将 Nil 移动到最后,因为第一个为 null 的元素具有我们添加的新元素的下一个引用 ( addingElelement)。

因为

““emptyList”也是“head”链接”

在我们的例子中 head 是Nil,但Nill不能有 next ,所以它必须创建新的第一个元素(它具有空值), next() 引用我们的 new addingElelement

我个人觉得它“太原始”而不是“那么优雅”。但这取决于,我猜。

任务导向的故事:

对于我的初始任务(为什么我开始考虑这个“奇怪”的列表行为[即使它是可变的])——我想将可变列表用于一个名为的类/对象Dictionary,它将保留Words在其中(字典默认没有任何单词)。而且我会有ddWord(wod:String)添加新单词的方法。现在我的实现将被更改(我不会使用 this LinkedList,而是使用MutableList。它似乎比以前的更易变):

object Dictionary {

  val words = new mutable.MutableList[Word]();

  def addWord(word: Word): Unit = {
    words += word;
  }

}

但可能的实现可能是这样的:

object Dictionary {

  var words = new mutable.LinkedList[Word]();

  def addWord(word: Word): Unit = {

    if (words.isEmpty) {
      words = words append( mutable.LinkedList[Word](word) ) // rely on append result
    } else {
      words append( mutable.LinkedList[Word](word) )
    }

  }

}

但是后来我必须使用var而不是val,并且我应该将每个新单词都转换为LinkedList,我的逻辑变得更加复杂。

于 2013-05-26T18:44:37.130 回答