2013-04-02 9 views
16

に追加このScalaは、可変のLinkedList

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) 

を確認してくださいなぜ2番目のコードスニペットは動作しますが、最初の1つのdoesntはいますか?これはScalaにあります。2.10

答えて

20

ドキュメントにはIf this is empty then it does nothing and returns that. Otherwise, appends that to this.と書かれています。それはまさに、あなたが観察したことです。あなたが本当に変更可能なリストが必要な場合は、私はあなたが私がリストである場合は、それが(リスト内の最初/最後の(Nil)要素に関連して理解として、それをあなたが

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) 
+2

なぜこの動作ですか?なぜ要素の数に関係なく自己に追加しないのですか?これは 'mutable'コレクションから期待されるものではありませんか? – weima

+0

私は考えがありません。正確な理由を知りたければ、公式のscalaメーリングリストを試してみるべきです。 – drexin

+0

実際にリストを変更するよりもずっと安いからだと思います。 IMHOは、実際に突然変異操作が突然変異を起こすという暗黙の契約を破っている。 – dOxxx

3

を行うことができますが、代わりにscala.collection.mutable.ListBufferを使用することをお勧めします空のNilは最初と最後の要素です)。

"primitive charm"のようになります。したがって、{Nil、newElement}のような結果を得るために、Nil以降に新しいデータを追加/追加しようとしません。もちろん

はそれがifリストが空でチェックすることができます(すべてのNilした後、最後の要素でなければなりません)その後、最後まで先頭にaddingListNilを置きます。しかし、これは「あまりにも賢い」と思います。

しかし、いずれにせよappend()このような結果「期待」を返します。この場合は

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

result = {"a", "b"}.それは返す「addingList」自体、および/しかし、最初のリストは変更されません。

我々はnext refにnewElementを割り当てようとした場合:

LinkedList(null, whatever) 

すなわち:結果

emptyList.next = LinkedList("whatever") 

我々はemtyListは次のように変更されていますのようにfist要素を作成するのは、next()に新しい/次の要素を割り当てるためです。したがって、最初の要素がヌルであるため、次に追加した新しい要素(addingElelement)を参照するため、Nilを最後まで移動します。

「『emptyListがNilである私たちのケースヘッドでヘッド『リンク』

と頭』もある」、それはしなければならないのでNillは、次のことはできませんので、新しいaddingElelementのnext()refereceで新しい最初の要素(null値を持つ)を作成します。

個人的に私はそれが「あまりにも原始的」で「あまりにもエレガント」ではないことがわかります。しかし、それは依存していると思います。

タスク指向の物語:私の最初のタスクのために

(私はこの「奇妙な」リストの行動について考え始めるなぜ[これは変更可能だにもかかわらず]) - 私はクラス/オブジェクトに対して変更可能なリストを使用していましたDictionaryと呼ばれ、Wordsを保持します(デフォルトでは、辞書には単語がありません)。そして、私は新しい単語を追加するためのddWord(wod:String)のようなメソッドを持っています。

object Dictionary { 

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

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

} 

しかし、可能な実装は次のように次のようになります。今の私の実装では、(私はこのLinkedListを使用するつもりはないが、むしろMutableListそれはそれは前のものよりより変更可能ようです)に変更されます:

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を使用する必要があり、私はにすべての新しいのWordを変換する必要があります、私の論理はもっと複雑になった。

関連する問題