В Scala (2.10) мне нужна неизменная коллекция SeqLike (поддерживающая индексация), которая предлагает пользователю интерфейс SetLike и не позволит дублировать элементы. В идеале это будет реализовывать как SetLike, так и SeqLike, но это невозможно, поэтому я должен выбрать один. Моя первая мысль была следующим образом:Уникальная последовательность Scala
sealed class IndexableSet[A] (private val values : Seq[A])
extends Set[A]
with SetLike[A,IndexableSet[A]]
{
override def empty : IndexableSet[A] = new IndexableSet[A](Seq[A]())
def + (elem : A) : IndexableSet[A] = values.contains(elem) match
{
case true => this
case false => new IndexableSet[A](values :+ elem)
}
def - (elem : A) : IndexableSet[A] = values.contains(elem)
{
case true => new IndexableSet[A](values.filter(_ != elem))
case false => this
}
def iterator = values.iterator
def contains(elem : A) = values.contains(elem)
def apply(index : Int) = values(index)
def length : Int = values.size
def contents : Seq[A] = values
}
Это подвергает подходящий интерфейс, но не sortability (нет SortBy или сортируются)
Я задаюсь вопросом, поэтому, следует ли изменить свою реализацию на что-то, которое реализует Seq и SeqLike вместо этого, и фальсифицирует интерфейс Set:
sealed class UniqueSeq[A] private (private val values : IndexedSeq[A])
extends SeqLike[A,UniqueSeq[A]]
with Seq[A]
with GenericTraversableTemplate[A,UniqueSeq]
{
def apply(idx : Int) : A = values(idx)
def iterator = values.iterator
def length = values.length
override def companion: GenericCompanion[UniqueSeq] = new GenericCompanion[UniqueSeq]()
{
def newBuilder[A]: Builder[A, UniqueSeq[A]] = new Builder[A, UniqueSeq[A]]
{
val elems = new ArrayBuffer[A]()
def +=(a:A) = { elems += a; this }
def clear() { elems.clear }
def result(): UniqueSeq[A] = new UniqueSeq[A](elems)
}
}
def + (elem : A) : UniqueSeq[A] = values.contains(elem) match
{
case true => this
case false => new UniqueSeq[A](values :+ elem)
}
def - (elem : A) : UniqueSeq[A] = values.contains(elem) match
{
case true => new UniqueSeq[A](values.filter(_ != elem))
case false => this
}
}
я не уверен, что лучше - или есть ли другой способ. Я знаю, что есть такие вещи, как TreeSet
, но свойство SortedSet не дает критической индексируемости.
Так вопросы:
- Есть явный победитель между этими двумя реализациями?
- Есть ли другой способ, который лучше, в стандартных коллекциях?
Это тема, которая приходит иногда и для меня тоже, и я действительно хотел было надежное решение ... Все, что я пытался и не видел так далеки были недостатки, такие как некорректная работа с 'map' или наличие слабого' contains (elem: Any) 'interface вместо' contains (elem: A) '... –