I want to create a new custom Scala collection from existing Set Collection which I can later extend with some additional functions.
For the moment, I am trying to make it behave as the standard collection Set
. I tried the following link : https://docs.scala-lang.org/overviews/core/custom-collections.html where they have a custom collection that extends on Map
. However extending on Set
seems a bit different and I am having a ton of type incompatibility that I am not able to resolve.
Here's my starting code : the parts I am not able to define are addOne
, substractOne
, contains
and iterator
.
import scala.collection._
class TestSet[A]
extends mutable.Set[A]
with mutable.SetOps[A, mutable.Set, TestSet[A]] {
override def empty: TestSet[A] = new TestSet
// Members declared in scala.collection.mutable.Clearable
override def clear(): Unit = immutable.Set.empty
// Members declared in scala.collection.IterableOps
override protected def fromSpecific(coll: IterableOnce[A]): TestSet[A] = TestSet.from(coll)
override protected def newSpecificBuilder: mutable.Builder[A, TestSet[A]] = TestSet.newBuilder
override def className = "TestSet"
//override def subtractOne(elem: A): TestSet.this.type = ???
//override def addOne(elem: A): TestSet.this.type = ???
//override def contains(elem: A): Boolean = ???
//override def iterator: Iterator[A] = {
//}
}
object TestSet {
def empty[A] = new TestSet[A]
def from[A](source: IterableOnce[A]): TestSet[A] =
source match {
case pm: TestSet[A] => pm
case _ => (newBuilder = source).result()
}
def apply[A](elem: A*): TestSet[A] = from(elem)
def newBuilder[A]: mutable.Builder[A, TestSet[A]] =
new mutable.GrowableBuilder[A, TestSet[A]](empty)
import scala.language.implicitConversions
implicit def toFactory[A](self: this.type): Factory[A, TestSet[A]] =
new Factory[A, TestSet[A]] {
def fromSpecific(it: IterableOnce[A]): TestSet[A] = self.from(it)
def newBuilder: mutable.Builder[A, TestSet[A]] = self.newBuilder
}
}
CodePudding user response:
I will interpret your question as "I want to do something similar as the Map-example from https://docs.scala-lang.org/overviews/core/custom-collections.html for a mutable Set but now am stuck with this code" and will try to answer that (ignoring any other aspects of your question).
What you need to understand is that mutable.Set
and mutable.SetOps
are just traits that provide some reusable parts of implementation, but they do not contain any actual data structures.
So if you want to implement your own implementation, you will have to provide the actual underlying data structure yourself (similar to how the PrefixMap
from that link has private var suffixes
and private var value
).
For example, you could use an underlying immutable Set like this:
class TestSet[A]
extends mutable.Set[A]
with mutable.SetOps[A, mutable.Set, TestSet[A]] {
// the underlying data structure
private var data = mutable.Set.empty[A]
// ATTENTION: your implementation was different and buggy
override def clear(): Unit = {
data = mutable.Set.empty
}
override def subtractOne(elem: A): TestSet.this.type = {
data = data - elem
this
}
override def addOne(elem: A): TestSet.this.type = {
data = data elem
this
}
override def contains(elem: A): Boolean = data.contains(elem)
override def iterator: Iterator[A] = {
data.iterator
}
// ...
}
Note that the above is just an example of what you could do in order to get your code to work - I'm not saying that it's a good idea.