LinkedHashMap
はマップの挿入順序を維持するために使用されますが、これは変更可能なマップでのみ機能します。挿入順序を保持する不変のMap
実装はどれですか?
ListMap は、リストベースのデータ構造を使用して不変マップを実装するため、挿入順序が保持されます。
scala> import collection.immutable.ListMap
import collection.immutable.ListMap
scala> ListMap(1 -> 2) + (3 -> 4)
res31: scala.collection.immutable.ListMap[Int,Int] = Map(1 -> 2, 3 -> 4)
scala> res31 + (6 -> 9)
res32: scala.collection.immutable.ListMap[Int,Int] = Map(1 -> 2, 3 -> 4, 6 -> 9)
次の拡張メソッド-Seq#toListMap
は、ListMap
sを使用する場合に非常に役立ちます。
scala> import scalaz._, Scalaz._, Liskov._
import scalaz._
import Scalaz._
import Liskov._
scala> :paste
// Entering paste mode (ctrl-D to finish)
implicit def seqW[A](xs: Seq[A]) = new SeqW(xs)
class SeqW[A](xs: Seq[A]) {
def toListMap[B, C](implicit ev: A <~< (B, C)): ListMap[B, C] = {
ListMap(co[Seq, A, (B, C)](ev)(xs) : _*)
}
}
// Exiting paste mode, now interpreting.
seqW: [A](xs: Seq[A])SeqW[A]
defined class SeqW
scala> Seq((2, 4), (11, 89)).toListMap
res33: scala.collection.immutable.ListMap[Int,Int] = Map(2 -> 4, 11 -> 89)
ListMap
は挿入順序を保持しますが、あまり効率的ではありません。ルックアップ時間は線形です。 _immutable.HashMap
_と_immutable.TreeMap
_の両方をラップする新しいコレクションクラスを作成することをお勧めします。不変マップはimmutable.HashMap[Key, (Value, Long)]
としてパラメーター化する必要があります。タプルのLong
は、_TreeMap[Long, Key]
_の対応するエントリへのポインターを提供します。その後、側面にエントリーカウンターを置きます。このツリーマップは、挿入順序に従ってエントリを並べ替えます。
挿入とルックアップは単純な方法で実装します。カウンターをインクリメントし、ハッシュマップに挿入し、カウンターキーのペアにツリーマップに挿入します。ルックアップにはハッシュマップを使用します。
ツリーマップを使用して反復を実装します。
削除を実装するには、ハッシュマップからキーと値のペアを削除し、タプルのインデックスを使用して、対応するエントリをツリーマップから削除する必要があります。