Das war eine ziemlich unerfreuliche Überraschung:
scala> Set(1, 2, 3, 4, 5)
res18: scala.collection.immutable.Set[Int] = Set(4, 5, 1, 2, 3)
scala> Set(1, 2, 3, 4, 5).toList
res25: List[Int] = List(5, 1, 2, 3, 4)
Das Beispiel an sich legt ein "Nein" als Antwort auf meine Frage nahe. Was ist dann mit ListSet
?
scala> import scala.collection.immutable.ListSet
scala> ListSet(1, 2, 3, 4, 5)
res21: scala.collection.immutable.ListSet[Int] = Set(1, 2, 3, 4, 5)
Diese scheint zu funktionieren, aber sollte ich mich auf dieses Verhalten verlassen? Welche andere Datenstruktur ist für eine unveränderliche Sammlung eindeutiger Elemente geeignet, bei der die ursprüngliche Reihenfolge beibehalten werden muss?
Übrigens, ich weiß Bescheid über distict
Methode in List
. Das Problem ist, dass ich die Eindeutigkeit der Elemente (unter Beibehaltung der Reihenfolge) auf Schnittstellenebene erzwingen möchte, also mit distinct
würde mein ordentliches Design durcheinander bringen
EDIT
ListSet
scheint auch nicht sehr zuverlässig zu sein:
scala> ListSet(1, 2, 3, 4, 5).toList
res28: List[Int] = List(5, 4, 3, 2, 1)
EDIT2
Auf der Suche nach einem perfekten Design habe ich dies ausprobiert:
scala> class MyList[A](list: List[A]) { val values = list.distinct }
scala> implicit def toMyList[A](l: List[A]) = new MyList(l)
scala> implicit def fromMyList[A](l: MyList[A]) = l.values
Das funktioniert tatsächlich:
scala> val l1: MyList[Int] = List(1, 2, 3)
scala> l1.values
res0: List[Int] = List(1, 2, 3)
scala> val l2: List[Int] = new MyList(List(1, 2, 3))
l2: List[Int] = List(1, 2, 3)
Das Problem ist jedoch, dass ich nicht die ganze Welt vor den Kopf stoßen möchte. MyList
außerhalb der Bibliothek. Gibt es eine Möglichkeit, die implizite Konvertierung beim Überschreiben zu haben? Zum Beispiel:
trait T { def l: MyList[_] }
object O extends T { val l: MyList[_] = List(1, 2, 3) }
scala> O.l mkString(" ") // Let's test the implicit conversion
res7: String = 1 2 3
Ich würde es gerne so machen:
object O extends T { val l = List(1, 2, 3) } // Doesn't work