web-dev-qa-db-ja.com

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番目のコードスニペットが機能するのに最初のコードスニペットが機能しないのはなぜですか?これはオンですScala 2.10

17
weima

ドキュメントには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)
23
drexin

私が理解しているように、それはリストの最初/最後(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)
_

つまりnext()を使用して新しい/次の要素を割り当てたため、最初の要素をnullとして作成します。したがって、nullである最初の要素には、追加した新しい要素(addingElelement)への次の参照があるため、Nilを最後に移動します。

なぜなら

「「emptyList」は「head」リンクでもあります」

この場合のheadはNilですが、Nillはnextを持つことができないため、next()が新しいaddingElelementを参照して、新しい最初の要素(null値を持つ)を作成する必要があります。

個人的には、「あまりにも原始的」であり、「あまりエレガント」ではないと思います。しかし、それは状況次第だと思います。

タスク指向のストーリー:

私の最初のタスク(なぜこの「奇妙な」リストの動作について考え始めるのか(可変であるにもかかわらず))-Dictionaryを保持するWordsというクラス/オブジェクトに可変リストを使用したかった(デフォルトでは辞書にはありません)任意の単語)。そして、新しい単語を追加するためのaddWord(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の代わりにvalを使用する必要があり、すべての新しいWordLinkedListに変換する必要があり、ロジックがより複雑になりました。

3
ses