2016-05-11 7 views
2

Wie ich in When should I choose Vector in Scala? lesen, die Frage, ob List oder Vector zu verwenden, erhält die gleiche Antwort in Scala wie in Java die Frage, ob LinkedList oder ArrayList zu verwenden. Die Antwort ist, wie Sie vielleicht wissen, "Vector/ArrayList in den meisten Fällen".Wie wird Vector als Standardimplementierung festgelegt?

In Scala List ist jedoch die ultimative Standardimplementierung von Traversable nach http://docs.scala-lang.org/tutorials/FAQ/collections. Ich denke, es ist nicht Vector, weil "es zu spät zur Party kam".

  1. Oder gibt es einen anderen Grund, dass Vector nicht dominanter ist?
  2. Wäre es nicht sinnvoll, ich setze IndexedSeq als die Standardimplementierung von Seq und daher Vector, um die ultimative Standardimplementierung von Traversable zu sein?
  3. Wie kann ich das tun?

Antwort

2

scala.mutable.Vector basierend auf trie structure so ist es technisch sehr viel komplexer als java.util.ArrayList. Diese Komplexität bedeutet, dass mehrere gemeinsame List s Commong-Suffixe leichter sein können als mehrere Vector s, die gemeinsame Präfixe haben.

Diese Eigenschaft bedeutet viel im funktionalen Stil, wo Sie oft eine Menge Operationen haben, die Sammlung nehmen und ihre Kopie nur ein bisschen zurückgeben, wie stack. Das Anhängen an große Vector könnte mehrere neue Objekte erzeugen, die auf List vorbereiteten - immer eine.

List ist sehr einfach zu verstehen und zu begründen. Es ist nur :: oder Nil.

Implementierung von Vector ist ziemlich versteckt, hat es "dirty" optimisations und konnte preferredly über seq extractors abgestimmt werden, die versteckt wahrscheinlich drops

Zufalls Haskell Entwickler optimiert verweist will Stream Standard Seq statt List sein. Einige scalaz Liebhaber - will more some symmetric Sequence in Std. Lib exportiert.

Sie können nicht Wahl von scala.Seq.apply ändern becasuse es basierend auf List als Ergebnis von ListBufferchosen newBuilder implementation. Allerdings können Sie Ihre eigene ähnliche Seq Fabrik wie

object Seq extends SeqFactory[Seq] { 
    implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] 
    def newBuilder[A]: Builder[A, Seq[A]] = new VectorBuilder[A] 
} 

So zusammenfassend schreiben:

  1. verlinkte Liste ist historisch dominierender Kollektionstyp in funktionalen Sprachen
  2. Ein weiterer Sequenztyp in einer anderen viel nützlicher sein könnte Domäne
  3. Sie können scala.Seq.apply nicht zu einem anderen generischen Typ "wechseln". Aber kann ein anderes Objekt unter dem Namen Seq importieren oder erstellen.

Ich persönlich finde Vector(...) Form nützliche und prägnant als . Dasselbe gilt für List(...) anstelle von Seq(...) oder LinearSeq(...).

+0

Könnten Sie drei kleine nummerierte Punkte schreiben, die die Antworten für meine drei Punkte zusammenfassen? Ich denke, ich verstehe, was du sagst (denke darüber ein wenig nach), bin mir aber nicht sicher, was die Antworten auf meine Fragen sind. – Make42

1

Die "Use Vector in den meisten Fällen" Antwort, die Sie in Java gewohnt sind, hält nicht in Scala, weil es eine andere Sprache ist, mit verschiedenen Mustern, Tools und Best Practices.

Die meisten Strukturen und Variablen sind unveränderlich, und die Algorithmen werden meistens im Hinblick auf die sequentielle Verarbeitung von Datenströmen ausgedrückt. Unter Berücksichtigung dieser beiden Beobachtungen muss man schlussfolgern, dass die Sammlung, die am besten zu den meisten Anwendungsfällen passt, tatsächlich eine verknüpfte Liste ist und keine Sammlung mit wahlfreiem Zugriff.

Also ist die kurze Antwort auf Ihre Frage # 3 "tun Sie es nicht". Eine etwas längere Version davon ist: sei explizit. Wenn Sie denken, Sie möchten IndexedSeq irgendwo verwenden, sagen Sie einfach so: val seq = IndexedSeq(1,2,3)

Verwandte Themen