scala - 如何定义不可变的 Set 比较方法将使用的自定义相等操作

标签 scala set overriding

我有一个不可变的类 Set[MyClass],我想使用 Set 方法 intersect 和 diff,但我希望它们使用我的自定义 equals 方法而不是默认对象相等性测试来测试相等性

我已经尝试覆盖 == 运算符,但它没有被使用。

提前致谢。

编辑:

intersect 方法是 GenSetLike 的具体值成员

规范:http://www.scala-lang.org/api/current/scala/collection/GenSetLike.html
来源:https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_1_final/src//library/scala/collection/GenSetLike.scala#L1

def intersect(that: GenSet[A]): Repr = this filter that

所以交集是使用过滤方法完成的。

另一个编辑:

过滤器在 TraversableLike 中定义

规范:http://www.scala-lang.org/api/current/scala/collection/TraversableLike.html

来源:https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_1_final/src//library/scala/collection/TraversableLike.scala#L1
def filter(p: A => Boolean): Repr = {
  val b = newBuilder
      for (x <- this) 
        if (p(x)) b += x
      b.result
}

我不清楚的是它在没有谓词的情况下调用时使用什么,p。这不是一个隐式参数。

最佳答案

仅当您未定义它们时,才会在 case 类中自动提供 equals 和 hashCode。

case class MyClass(val name: String) {
  override def equals(o: Any) = o match {
    case that: MyClass => that.name.equalsIgnoreCase(this.name)
    case _ => false
  }
  override def hashCode = name.toUpperCase.hashCode
}

Set(MyClass("xx"), MyClass("XY"), MyClass("xX"))
res1: scala.collection.immutable.Set[MyClass] = Set(MyClass(xx), MyClass(XY))

如果你想要的是引用相等,还​​是写equals和hashCode,防止自动生成,从AnyRef调用版本
  override def equals(o: Any) = super.equals(o)
  override def hashCode = super.hashCode

接着就,随即:
Set(MyClass("x"), MyClass("x"))
res2: scala.collection.immutable.Set[MyClass] = Set(MyClass(x), MyClass(x))

您不能覆盖 ==(o: Any)来自 AnyRef,它是密封的并且总是调用 equals。如果您尝试定义一个新的(重载的)==(m: MyClass) ,不是Set调用,所以它在这里没用,一般来说非常危险。

至于调用filter ,它起作用的原因是Set[A]Function[A, Boolean] .是的,equals使用时,您会看到函数实现( apply )是 contains 的同义词,以及 Set 的大多数实现使用 ==在包含(SortedSet 使用 Ordering 代替)。和==来电equals .

注:我第一次执行equals如果要对 MyClass 进行子类化,它又快又脏,而且可能很糟糕。如果是这样,您至少应该检查类型相等( this.getClass == that.getClass )或更好地定义 canEqual方法(您可以阅读 Daniel Sobral 的 this blog)

关于scala - 如何定义不可变的 Set 比较方法将使用的自定义相等操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7681183/

相关文章:

javascript - 如何覆盖我的插件的 jQuery 全局函数?

scala - Slick 中按日期时间排序

java - Java 类访问时的 Scala 可见性

python - 如何在python中将集合元素添加到字符串

c++ - 如何为一组对重载比较运算符?

C++继承函数中的默认操作

iphone - iOS-覆盖UITextView方法?

java - Scala 中使用 java.util.Base64 的非法 base64 字符 "a"

scala - 为什么嵌套的 FlatMaps 会在 Scala 中炸毁堆栈?

python - 找到最小的解决方案集,如果存在(两个乘数)