Pourquoi la sortie de cette comparaison produit-elle true
?
import scala.collection.immutable.ListSet Set(1) == ListSet(1) // Expect false //Output res0: Boolean = true
Et dans un sens plus général, comment la comparaison est-elle réellement effectuée?
3 Réponses :
Cette classe implémente des ensembles immuables en utilisant des données basées sur des listes structure.
ListSet est donc aussi un ensemble mais avec une implémentation concrète (basée sur des listes).
De Égalité des collections Scala :
Les bibliothèques de collections ont une approche uniforme de l'égalité et du hachage. L'idée est, tout d'abord, de diviser les collections en ensembles, cartes et séquences.
...
Par contre, au sein d'une même catégorie, les collections sont égales si et seulement si elles ont les mêmes éléments
Dans votre cas, les deux collections sont considérées comme des ensembles et elles contiennent les mêmes éléments, par conséquent, elles sont égales.
C'est correct, mais juste une mise en garde pour les séquences: List (1, 2, 3) == Vector (1, 2, 3)
mais List (1, 2, 3) ! = Array (1, 2, 3)
et Array (1, 2, 3)! = Array (1, 2, 3)
- voir aussi stackoverflow .com / questions / 29008500 /…
Array
ne fait pas partie du package collections
, il y a plus d'informations ici sur les particularités de Array
. S'il est converti en Seq [Int]
(qui l'envelopperait comme un WrappedArray
), alors il sera égal à une List
équivalente
Étant donné que la chaîne d'héritage Essentiellement, il vérifie si l'autre objet est également un Ainsi, la classe exacte utilisée pour représenter l'ensemble au moment de l'exécution n'est pas pertinente, ce qui compte c'est que l'objet comparé soit également un Set <: genset gensetlike> est un peu longue, il n'est peut-être pas immédiatement évident de savoir où chercher le code de
est égal à
, donc je j'ai pensé peut-être le citer ici: /** 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
, et si oui , il tente d'effectuer des vérifications rapides (comme comparer size
et appeler canEqual
), et si les tailles sont égales, il vérifie si cet ensemble est un sous-ensemble d'un autre set, vraisemblablement en vérifiant chaque élément. GenSet
et qu'il ait les mêmes éléments.
Cela ne vaut rien que l'implémentation se résume à
set1.forall (set2.contains)
(après une vérification de la taille, etc.), ce qui signifie que si vous comparez de grands ensembles et que vous vous souciez des performances, leListSet
doit venir en premier.… Par exemple
(0 à 100000) .to [Set] == (0 à 100000) .to [ListSet]
prend ~ 14 secondes sur mon ordinateur portable, tandis que l'inverse est instantané.