Scala Collectionsの矛盾
-
28-09-2019 - |
質問
Scala Collections APIのセットとリストの間に一貫性がないのはなぜですか?
たとえば、不変のセットだけでなく、可変性もあります。後者を使用したい場合は、単にこれを行うことができます。
val set = Set[A]()
set += new A
ただし、それ自体、可変リストはありません。リストを使用して同様のコードスニペットを書きたい場合、どのデータ構造を使用するか? LinkedListは、可変であるが、NO +=メソッドが定義されているため、優れた候補者のように聞こえます。 ListBufferは要件を満たしているようですが、リストではありません。
2.8コレクションのドキュメントを読んだ後、私は結論に達しましたMutableListはおそらく最適です。
Scala.collection.mutable.listがあればいいのにと思います。
解決
この理由は、Javaが 機能 List
そうでないことを意味するタイプ(つまり、 java.util.List
ではありません リスト).
機能的なプログラミング言語が持つことはおそらく意味がありません 可変 List
そのようなタイプは矛盾表現です。したがって、 ListBuffer
また ArrayBuffer
. 。または単に使用してください IndexedSeq
, 、そのうち、可変で不変の実装があります
他のヒント
のシーケンス/リストアナログ Set
Scalaのコレクションライブラリはそうです Seq
. List
特別な、不変の実装です Seq
, 、 そのまま Vector
. ArrayBuffer
また ListBuffer
の典型的な実装です mutable.Seq
.
ArraySeqは、 +=が非常に遅いことを除いて、探しているものかもしれません。 java.util.arraylistを使用してcollection.javaconversions._を使用することもできます。
Scalaには、Constant Time Index(JavaのArrayListなど)を備えた優れた可変リストのようなコレクションがないようです。
いずれにせよ、「リスト」とは、「scala.immutable.list」というタイプを正確に指すことに注意してください。したがって、SEQ(またはその他の抽象的なコレクションタイプ)は、不変/可変コレクションを一般化したい場合は、「リスト」ではなく、メソッドで期待されるタイプです。
より理想的なのは、IndexedEdeqを再Queringすることです。これは、インデックス操作がそのコレクションのパフォーマンスであることを意味します。ただし、ListBufferがそのカテゴリに分類されるかどうかはわかりません。
なぜなら Set
単なる特徴です - それは抽象的であり、実装が必要です。だから、あるクラスについて話すことができます mutable.Set
また immutable.Set
.
その間、 List
クラスであり、(要約)特性の実装です immutable.LinearSeq
. 。他のクラスもありません List
. 。ただし、そこにいることがわかります は a mutable.LinearSeq
特性。
Javaの用語では、インターフェイスをクラスと比較しています - それらは明確です。
忘れないで scala.collection.mutable.{LinkedList,DoubleLinkedList}
. 。彼らは可変であり、彼らはそうです LinearSeq
. 。突然変異は少し奇妙です - あなたは elem
参照、およびに尾を割り当てます next
参照。
たとえば、このループはすべての負の値をゼロに変更します。
val lst = collection.mutable.LinkedList(1, -2, 7, -9)
var cur = lst
while (cur != Nil) {
if (cur.elem < 0) cur.elem = 0
cur = cur.next
}
このループは、リストから2番目の要素を削除します。
var cur = lst
while (cur != Nil && cur.next != Nil) {
cur.next = cur.next.next
cur = cur.next
}
私は、これらが不変のリストよりも優れていることを示唆していません。 Scalaには、データ構造のクラスで見たものとかなり似ている可変リストがあることを指摘しています。