Scala - Сравнение коллекций - Почему Set (1) == ListSet (1)? - PullRequest
0 голосов
/ 05 февраля 2019

Почему выходные данные этого сравнения выводят true?

import scala.collection.immutable.ListSet

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

//Output
res0: Boolean = true 

И в более общем смысле, как на самом деле выполняется сравнение?

Ответы [ 3 ]

0 голосов
/ 05 февраля 2019

С Равенство коллекций Scala :

Библиотеки коллекций имеют единый подход к равенству и хэшированию.Идея состоит в том, чтобы, во-первых, разделить коллекции на наборы, карты и последовательности.

...

С другой стороны, в пределах одной категории коллекции равны тогда и только тогда, когда ониимеют одинаковые элементы

В вашем случае обе коллекции считаются наборами и содержат одинаковые элементы, следовательно, они равны.

0 голосов
/ 05 февраля 2019

Поскольку цепочка наследования 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 и имеет те же элементы.

0 голосов
/ 05 февраля 2019

Документация Scala 2.12.8 :

Этот класс реализует неизменяемые наборы с использованием структуры данных на основе списка.

Таким образом, ListSet являетсяустановить тоже, но с конкретной реализацией (на основе списка).

...