2013-04-02 11 views
16

Proszę sprawdzićscala dołączyć do zmienny LinkedList

import scala.collection.mutable.LinkedList 

var l = new LinkedList[String] 

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

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

ale

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) 

Dlaczego drugi prace fragmentu kodu ale pierwszy nie robi? To jest na Scala 2.10

Odpowiedz

20

Dokumentacja mówi If this is empty then it does nothing and returns that. Otherwise, appends that to this.. Dokładnie to, co zaobserwowałeś. Jeśli naprawdę potrzebujesz listę zmienny, proponuję użyć scala.collection.mutable.ListBuffer zamiast z nim można zrobić

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

ale dlaczego to zachowanie? dlaczego nie dołączyć do siebie bez względu na liczbę elementów? czy nie jest to oczekiwane z kolekcji "zmienne"? – weima

+0

Najwyraźniej nie mam pomysłu. Jeśli chcesz poznać dokładny powód, powinieneś wypróbować oficjalną listę mailingową scala. – drexin

+0

Zgaduję, że to dlatego, że jest o wiele tańsze niż modyfikowanie listy. Chociaż IMHO łamie implikowaną umowę, że operacje mutacji będą faktycznie mutować listę. – dOxxx

3

Jak rozumiem to jest związane z pierwszym/(Nil) elementu na liście (jeśli lista jest pusty Nil to pierwszy i ostatni element w tym samym czasie).

LinkedList (nadal) podąża za strategią "primitive charm". Tak więc nie próbuje dodawać/dołączać nowych danych do/po Nil, aby uzyskać taki wynik: {Nil, newElement}. (Wszakże Nil powinna być ostatnim elementem)

Oczywiście może to sprawdzić if lista jest pusta następnie umieścić addingList na początku i Nil do końca. Ale myślę, że to byłoby "zbyt mądre".

Ale i tak append() powraca „Oczekiwany” Wynik tak:

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

result = {"a", "b"}. W tym przypadku zwraca „addingList” sam i/ale nie zmienia wstępną listę.

Jeśli spróbujemy przypisać newElement do next Ref:

emptyList.next = LinkedList("whatever") 

W rezultacie mielibyśmy emtyList zmieniony tak:

LinkedList(null, whatever) 

Tj tworzy element pięści jako zerowy, ponieważ użyliśmy next() przypisując mu nowy/następny element. Tak więc przenosi zero do końca, ponieważ pierwszy element, który ma wartość zerową, ma następne odniesienie do nowego elementu, który dodaliśmy (addingElelement).

Ponieważ

"the "emptyList" jest także "głowa" link"

i głowa w naszym przypadku głowicy jest Nil, ale Nill nie może mieć obok, więc to musi utwórz nowy pierwszy element (który ma wartość pustą) z następną() referencją do naszego nowego addingElelement.

Osobiście uważam to za "zbyt prymitywne", a nie "tak eleganckie". Ale to zależy, jak sądzę.

Zadanie zorientowane historia:

Dla mojego początkowego zadania (dlaczego ja zacząć myśleć o tym „obcym” lista zachowań [mimo że jest zmienny]) - chciałem użyć zmienny listy dla klasy/obiektu o nazwie Dictionary, która zachowałaby w sobie Words (słownik domyślnie nie zawiera żadnych słów). I będę miał metody takie jak ddWord(wod:String) do dodawania nowych słów. Na razie moja realizacja zostanie zmieniony (nie będę korzystać z tej LinkedList, ale raczej MutableList Wydaje się, że jest bardziej zmiennyniż poprzedni.):

object Dictionary { 

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

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

} 

Ale możliwa realizacja może być tak :

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)) 
    } 

    } 

} 

Ale potem muszę używać var zamiast val i mam przekształcić każdy nowy Słowo do LinkedList, a moja logika stała się bardziej skomplikowana.