Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - Collection comparison - Why is Set(1) == ListSet(1)?

Why is the output of this comparison outputs true?

import scala.collection.immutable.ListSet

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

//Output
res0: Boolean = true 

And in a more general sense, how the comparison is actually done?

like image 850
Aaron_ab Avatar asked Dec 07 '22 12:12

Aaron_ab


2 Answers

Since the inheritance chain Set <: GenSet <: GenSetLike is a bit lengthy, it might be not immediately obvious where to look for the code of equals, so I thought maybe I quote it here:

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
  }

Essentially, it checks whether the other object is also a GenSet, and if yes, it attempts to perform some fail-fast checks (like comparing size and invoking canEqual), and if the sizes are equal, it checks whether this set is a subset of another set, presumably by checking each element.

So, the exact class used to represent the set at runtime is irrelevant, what matters is that the compared object is also a GenSet and has the same elements.

like image 149
Andrey Tyukin Avatar answered Dec 25 '22 15:12

Andrey Tyukin


From Scala collections equality:

The collection libraries have a uniform approach to equality and hashing. The idea is, first, to divide collections into sets, maps, and sequences.

...

On the other hand, within the same category, collections are equal if and only if they have the same elements

In your case, both collections are considered sets and they contain the same elements, hence, they're equal.

like image 28
Chirlo Avatar answered Dec 25 '22 14:12

Chirlo