新しいものを作成せず、非推奨のソリューションを使用せList
ずに、Scala 2.7.5 でa に要素を追加するにはどうすればよいですか。List
6 に答える
ListBuffer
一定時間の追加を提供する を使用できます。
val buffer = new scala.collection.mutable.ListBuffer[Int]
buffer += 1
buffer += 2
val list = buffer.toList
List
これは、インターフェイスと同等ではない、scala で非常に具体的な意味を持つことを指摘する価値がありjava.util.List
ます。headとtailを持つ再帰的なデータ構造をList
表す、封印された抽象クラスです。(scala には Java のリストのような構造が存在し、そのうちのいくつかは変更可能です。)
Scala のList
は不変です。リストを変更することはできませんが、既存のリストの前に新しいリストを作成することはできます (これにより、新しいオブジェクトが返されます)。それらは不変ですが、構造体は、オブジェクトの作成に関して、たとえば、に追加するよりも高価ではありません。java.util.LinkedList
この+
メソッドは非効率的であるため、正当な理由で廃止されました。代わりに次を使用します。
val newList = theList ::: List(toAppend)
別の方法は、2 つの反転を先頭に追加することだと思います。
val newList = (toAppend :: theList.reverse).reverse
これがより効率的であるとは思えません!一般に、追加動作が必要な場合は、先頭に追加してからreverse
(リストにアクセスする必要がある時点で) を使用します。
val newList = toAppend :: theList
//much later! I need to send the list somewhere...
target ! newList.reverse
Scala 2.7.5のリストに要素を追加する非推奨の方法?
それは存在しません、そしてそれは決して存在しません。
新しいリストを作成せず、非推奨のソリューションを使用せずに、Scala 2.7.5 のリストに要素を追加するにはどうすればよいですか。
使用::
:
val newList = element :: oldList
または、list
が の場合var
、
list ::= element
new は作成せずList
(ただし、cons::
とも呼ばれるnew を作成します)、それに要素を追加します。
新しいシーケンスを作成せずに要素をシーケンスに追加する場合は、可変データ構造を使用します。
+=
リストのメソッドは末尾に要素を追加するため、非推奨です。これはコストがかかります。リストに要素を追加する最も安価な方法は、 を使用してヘッドに追加すること::=
です。
したがって、非推奨の警告は、プログラムを再設計して、追加する代わりに先頭に追加する必要があるという微妙なヒントです。
scala> var l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)
scala> l ::= 4
scala> l
res1: List[Int] = List(4, 1, 2, 3)
::=
( and +=
on avar
は実際のメソッドではなく、 sugar forなどであることに注意してくださいl = l :: elem
)
以下は、特定の操作リストの実装には当てはまりません。修正してくれたsschaefに感謝します。
ここで言及されていない非常に重要な点は、別のコレクションから新しいコレクションを作成することは、必ずしも Java の場合ほど Scala ではコストがかからないということです。この概念は持続性と呼ばれます。Daniel Spiewak は、彼の記事http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-1で説明しています。
関連するセクションのスニペットを次に示します。
もちろん、頭に浮かぶ自然な質問は、パフォーマンスはどうですか? 各呼び出しが実際にすべての再帰呼び出しに対して真新しい Set を作成する場合、非効率的なオブジェクトのコピーとヒープ操作が大量に必要になるのではないでしょうか? 結局のところ、これは実際には当てはまりません。はい、ターンごとに新しいインスタンスを作成する必要があります。これは、JVM では比較的高価な操作ですが、ほとんど何もコピーされていません。Scala のすべての不変データ構造には、永続性と呼ばれるプロパティがあります。つまり、新しいコンテナを作成するときに、古いコンテナからデータをコピーするのではなく、新しいコンテナを古いコンテナに参照させ、そのすべてのコンテンツを独自のものでした。
そのため、変更可能なリストを使用する方が費用はかかりませんが、Java での場合ほど問題にはなりません。
これでうまくいくはずです: http://www.scala-lang.org/docu/files/api/scala/collection/mutable/SingleLinkedList.html#append%28This%29
またはこれ: http://www.scala-lang.org/docu/files/api/scala/collection/mutable/ListBuffer.html#%2B%3A%28A%29
基本的なトリックは、変更可能なリスト (または同様の機能を持つクラス) を使用することです。