scala追加到一个可变的LinkedList

时间:2013-04-02 10:18:42

标签: scala collections mutable

请检查

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

2 个答案:

答案 0 :(得分:21)

文档说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)

答案 1 :(得分:3)

据我所知,它与列表中的第一个/最后一个(Nil)元素相关(如果列表为空Nil是同一个第一个和最后一个元素)。

LinkedList(仍然)遵循“ primitive charm ”策略。因此,它不会尝试在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分配给next ref:

   emptyList.next = LinkedList("whatever")

结果我们将emtyList更改为:

 LinkedList(null, whatever)

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

因为

  

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

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

我个人认为它“太原始”而不是“太优雅”。但这取决于我的想法。

以任务为导向的故事:

对于我的初始任务(为什么我开始考虑这个'奇怪的'列表行为[即使它是可变的]) - 我想使用一个名为Dictionary的类/对象的可变列表来保持{{ 1}}在它里面(字典默认没有任何单词)。我会像Words这样的方法来添加新单词。现在我的实现将会更改(我不会使用此ddWord(wod:String),而是使用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,我应该将每个新的 Word 转换为val,我的逻辑变得更加复杂。