web-dev-qa-db-fra.com

Immuable Scala Implémentation de carte qui préserve l'ordre d'insertion

LinkedHashMap est utilisé pour conserver l'ordre d'insertion dans la carte, mais cela ne fonctionne que pour les cartes mutables. Quelle est l'implémentation immuable de Map qui préserve l'ordre d'insertion?

51
Matroska

ListMap implémente une carte immuable en utilisant une structure de données basée sur une liste et préserve ainsi l'ordre d'insertion.

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)

La méthode d'extension suivante - Seq#toListMap peut être très utile lorsque vous travaillez avec ListMaps.

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)
52
missingfaktor

Bien que ListMap préserve l'ordre d'insertion, il n'est pas très efficace - par exemple le temps de recherche est linéaire. Je vous suggère de créer une nouvelle classe de collection qui enveloppe à la fois le immutable.HashMap Et le immutable.TreeMap. La carte immuable doit être paramétrée comme immutable.HashMap[Key, (Value, Long)], où le Long dans le tuple vous donne le pointeur vers l'entrée correspondante dans le TreeMap[Long, Key]. Vous gardez ensuite un compteur d'entrée sur le côté. Cette arborescence triera les entrées selon l'ordre d'insertion.

Vous implémentez l'insertion et la recherche de manière simple - incrémentez le compteur, insérez-le dans la carte de hachage et insérez-le dans la paire de contre-clés dans le treemap. Vous utilisez la carte de hachage pour la recherche.

Vous implémentez l'itération en utilisant l'arborescence.

Pour implémenter la suppression, vous devez supprimer la paire clé-valeur de la carte de hachage et utiliser l'index du tuple pour supprimer l'entrée correspondante de la carte d'arborescence.

22
axel22