我如何定义将由不可变集合比较方法使用的自定义相等操作
我有一个不可变的类Set [MyClass] Set,我想使用Set方法intersect和diff,但我希望他们使用我的自定义equals方法testing相等性,而不是默认的对象相等性testing
我已经尝试覆盖==运算符,但它没有被使用。
提前致谢。
编辑:
交集方法是GenSetLike的具体值成员
规格: http : //www.scala-lang.org/api/current/scala/collection/GenSetLike.html src: 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 所以交叉口是使用过滤方法完成的。
又一个编辑:
filter在TraversableLike中定义
规格: http : //www.scala-lang.org/api/current/scala/collection/TraversableLike.html
src: 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)) 
 你不能覆盖来自AnyRef的==(o: Any) ,它是封闭的,总是调用equals。 如果你尝试定义一个新的(重载的) ==(m: MyClass) ,那不是Set调用的那个,所以在这里是没用的,而且一般来说相当危险。 
 至于filter的调用,它的工作原因是Set[A]是一个Function[A, Boolean] 。 是的,使用equals ,你会看到函数实现( apply )是contains一个同义词,并且Set use == in的大部分实现都包含在其中( SortedSet使用Ordering )。  ==电话equals 。 
 注意:我的第一个equals的实现是快速和肮脏的,如果MyClass被子类化,可能会很糟糕。 如果是这样,至less应该检查types是否相等( this.getClass == that.getClass )或者更好的定义一个canEqual方法(您可以阅读Daniel Sobral的博客 ) 
 你也需要覆盖.hashCode 。 当您覆盖.equals ,几乎总是这样,因为.hashCode经常用作对.equals更便宜的.equals ; 任何两个相等的对象必须具有相同的散列码。 我猜你正在使用的对象的默认hashCode不尊重这个属性相对于你自定义的相等性,并且Set实现正在做基于哈希代码的假设(所以从来没有甚至调用你的相等操作)。 
 查看Scala文档Any.equals和Any.hashCode : http : //www.scala-lang.org/api/rc/scala/Any.html 
  这个答案显示了一个自定义的可变集合与用户定义的平等 。 通过用Vectorreplace内部存储并在每次操作时返回自身的修改副本,可以使其不可变 
“直接覆盖==是不可能的,因为它被定义为类Any中的最后一个方法。也就是说,Scala将==视为在类Any中定义如下:
  final def == (that: Any): Boolean = if (null eq this) {null eq that} else {this equals that} 
“从编程斯卡拉,第二版