You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Scala中创建继承自Set的自定义集合?

解决Scala自定义可变Set的类型兼容与方法实现问题

你的核心问题是没有为自定义Set提供底层数据存储,并且部分方法实现错误(比如clear)。下面是修正后的完整代码,完全兼容Scala标准可变Set的行为,同时保留扩展能力:

import scala.collection._

class TestSet[A]
  extends mutable.Set[A]
    with mutable.SetOps[A, mutable.Set, TestSet[A]] {

  // 用Scala自带的可变HashSet作为底层存储,避免重复造轮子
  private val underlying: mutable.HashSet[A] = mutable.HashSet.empty[A]

  // 返回空的TestSet实例
  override def empty: TestSet[A] = new TestSet[A]

  // 清空底层存储,符合Clearable的Unit返回值要求
  override def clear(): Unit = underlying.clear()

  // 从IterableOnce创建TestSet,委托给伴生对象的from方法
  override protected def fromSpecific(coll: IterableOnce[A]): TestSet[A] = TestSet.from(coll)

  // 返回TestSet的Builder,委托给伴生对象
  override protected def newSpecificBuilder: mutable.Builder[A, TestSet[A]] = TestSet.newBuilder

  // 自定义集合的类名,用于toString等输出
  override def className: String = "TestSet"

  // 添加元素:委托给底层HashSet,返回自身(符合mutable集合的链式调用要求)
  override def addOne(elem: A): TestSet.this.type = {
    underlying.addOne(elem)
    this
  }

  // 删除元素:同样委托给底层HashSet,返回自身
  override def subtractOne(elem: A): TestSet.this.type = {
    underlying.subtractOne(elem)
    this
  }

  // 检查元素是否存在:直接用底层HashSet的contains
  override def contains(elem: A): Boolean = underlying.contains(elem)

  // 返回迭代器:委托给底层HashSet的迭代器
  override def iterator: Iterator[A] = underlying.iterator
}

object TestSet {
  // 创建空的TestSet
  def empty[A]: TestSet[A] = new TestSet[A]

  // 从IterableOnce创建TestSet,处理TestSet实例的直接返回,其他情况用Builder构建
  def from[A](source: IterableOnce[A]): TestSet[A] =
    source match {
      case ts: TestSet[A] => ts
      case _ => (newBuilder[A] ++= source).result()
    }

  // 可变参数创建TestSet
  def apply[A](elem: A*): TestSet[A] = from(elem)

  // 返回TestSet的Builder,用GrowableBuilder包装empty实例
  def newBuilder[A]: mutable.Builder[A, TestSet[A]] =
    new mutable.GrowableBuilder[A, TestSet[A]](empty[A])

  // 隐式转换为Factory,方便集合操作的隐式调用
  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
    }
}

关键修改说明:

  • 底层存储:新增private val underlying,用标准mutable.HashSet作为内部存储,避免自己实现哈希表等复杂逻辑,同时保证性能和兼容性。
  • clear方法修正:原来的实现返回了不可变Set,不符合Clearable接口的Unit返回要求,现在直接清空底层存储。
  • 核心方法实现:addOne、subtractOne、contains、iterator全部委托给底层HashSet实现,既符合标准Set的行为,又减少重复代码。
  • 类型一致性:所有方法的返回类型严格遵循SetOps的要求,比如addOne返回TestSet.this.type,保证链式调用的类型正确。

扩展建议

如果后续要添加自定义功能,比如元素添加时的日志、自定义过滤规则等,只需要在对应的方法中添加逻辑即可,比如修改addOne:

override def addOne(elem: A): TestSet.this.type = {
  println(s"Adding element: $elem")
  underlying.addOne(elem)
  this
}

内容的提问来源于stack exchange,提问作者Usr654789

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:35:28