如何在Scala中创建一个扩展集的自定义集合?

xytpbqjk  于 2022-12-26  发布在  Scala
关注(0)|答案(1)|浏览(132)

我想从现有的Set集合创建一个新的自定义Scala集合,稍后可以使用一些附加函数扩展该集合。
目前,我正尝试让它像标准集合Set一样工作。https://docs.scala-lang.org/overviews/core/custom-collections.html,其中他们有一个在Map上扩展的自定义集合。但是在Set上扩展似乎有点不同,我有大量的类型不兼容问题无法解决。
下面是我的启动代码:我不能定义的部分是addOnesubstractOnecontainsiterator

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
    }

}
dwthyt8l

dwthyt8l1#

我会把你的问题解释为“我想做一些类似于https://docs.scala-lang.org/overviews/core/custom-collections.html中的Map示例的事情,但是现在我被这段代码卡住了”,我会尝试回答这个问题(忽略你问题的任何其他方面)。
您需要理解的是,mutable.Setmutable.SetOps只是提供一些可重用实现部分的trait,但它们不包含任何实际的数据结构。
因此,如果您想实现自己的实现,就必须自己提供实际的底层数据结构(类似于来自该链接的PrefixMap具有private var suffixesprivate var value)。
例如,您可以使用下面这样的底层不可变Set:

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
  }
  
  // ...
}

请注意,以上只是一个例子,说明了为了让代码正常工作,您可以做些什么--我并不是说这是一个好主意。

相关问题