Scala-集合比较-为什么Set(1)== ListSet(1)?

时间:2019-02-05 10:24:52

标签: scala collections comparison

为什么此比较输出为true

import scala.collection.immutable.ListSet

Set(1) == ListSet(1) // Expect false

//Output
res0: Boolean = true 

从更一般的意义上讲,实际上是如何进行比较的?

3 个答案:

答案 0 :(得分:7)

由于继承链Set <: GenSet <: GenSetLike有点长,因此在哪里寻找equals的代码可能并不立刻明显,所以我想也许我在这里引用它:

GenSetLike.scala

  /** Compares this set with another object for equality.
   *
   *  '''Note:''' This operation contains an unchecked cast: if `that`
   *        is a set, it will assume with an unchecked cast
   *        that it has the same element type as this set.
   *        Any subsequent ClassCastException is treated as a `false` result.
   *  @param that the other object
   *  @return     `true` if `that` is a set which contains the same elements
   *              as this set.
   */
  override def equals(that: Any): Boolean = that match {
    case that: GenSet[_] =>
      (this eq that) ||
      (that canEqual this) &&
      (this.size == that.size) &&
      (try this subsetOf that.asInstanceOf[GenSet[A]]
       catch { case ex: ClassCastException => false })
    case _ =>
      false
  }

本质上,它检查另一个对象是否也是GenSet,如果是,它尝试执行一些快速失败检查(例如比较size和调用canEqual),如果大小相等,则大概通过检查每个元素来检查该集合是否是另一个集合的子集。

因此,用于在运行时表示集合的确切类无关紧要,重要的是,被比较的对象也是GenSet并且具有相同的元素。

答案 1 :(得分:4)

来自Scala collections equality

  

集合库对相等性和散列采用统一的方法。首先是将集合划分为集合,图和序列。

     

...

     

另一方面,在同一类别中,当且仅当它们具有相同的元素时,集合才相等

在您的情况下,两个集合都被视为集合,并且它们包含相同的元素,因此它们是相等的。

答案 2 :(得分:3)

Scala 2.12.8 documentation

  

此类使用基于列表的数据实现不可变集   结构。

所以ListSet也是一个集合,但是具有具体的(基于列表的)实现。