Scala SetBuffer

Viewed 271

I am trying to update my project from Scala 2.12 to Scala 2.13. I see that the Scala team has done a lot of changes on the collection side.

I have a SetBuffer that looks like this in Scala 2.12

object SetBuffer extends MutableSetFactory[SetBuffer] {
  override def empty[Elem] = new SetBuffer[Elem](Set.empty)

  def apply[Elem](initialSet: Iterable[Elem]): SetBuffer[Elem] =
    new SetBuffer[Elem](initialSet.toSet)

  override def newBuilder[Elem] = new SetBufferBuilder[Elem]()

  class SetBufferBuilder[Elem] extends mutable.GrowingBuilder[Elem, SetBuffer[Elem]](SetBuffer.empty) {
    override def result(): SetBuffer[Elem] =
      new SetBuffer[Elem](elems.getDelta)
  }
}

class SetBuffer[ElemType](initialSet: Set[ElemType])
  extends mutable.HashSet[ElemType]
    with mutable.SetLike[ElemType, SetBuffer[ElemType]]
    with GenericSetTemplate[ElemType, SetBuffer] {

  initialSet.map(+=)

  override def companion: SetBuffer.type = SetBuffer

  def getDeltaBuffer: SetBuffer[ElemType] = {
    SetBuffer[ElemType]((this -- initialSet).toSeq:_*)
  }

  def getDelta: immutable.Set[ElemType] = {
    val deltaElements = (this -- initialSet).toSeq
    immutable.Set[ElemType](deltaElements: _*)
  }

  def ++(that: Iterable[ElemType]): SetBuffer[ElemType] =
    SetBuffer(toIterable ++ that)

  def append(that: Iterable[ElemType]): Unit = this ++= that

  def ++=(that: Iterable[ElemType]): Unit = that.map(+=)
}

Scala 2.13 removed mutable.SetLike[ElemType, SetBuffer[ElemType]] and GenericSetTemplate[ElemType, SetBuffer] and made mutable.HashSet final. Is there a way to rewrite the code in the class SetBuffer[ElemType](initialSet: Set[ElemType]) so it will behave the same and have the same performances?

1 Answers

Two ideas come to my mind.

First - you can try to use https://www.scala-lang.org/api/current/scala/collection/mutable/LinkedHashSet.html that seems to not be final. I am not sure if it's possible and I didn't search for performance characteristics.

Second, you go for composition over inheritance. Wrap the instance of HashSet and delegate all calls to it. You would have to implement quite a few interfaces to achieve the same behaviour though.

Related