web-dev-qa-db-fra.com

Scala Les ensembles contiennent les mêmes éléments, mais sameElements () renvoie false

En travaillant à travers le Scala exercices sur Iterables , j'ai rencontré le comportement étrange suivant:

val xs = Set(5,4,3,2,1)
val ys = Set(1,2,3,4,5)
xs sameElements ys       // true

val xs = Set(3,2,1)
val ys = Set(1,2,3)
xs sameElements ys       // false - WAT?!

Ces ensembles ont sûrement les mêmes éléments et devraient ignorer l'ordre; et pourquoi cela fonctionne-t-il comme prévu uniquement pour le plus grand ensemble?

53
DNA

La bibliothèque de collections Scala fournit des implémentations spécialisées pour les ensembles de moins de 5 valeurs (voir source ). Les itérateurs de ces implémentations renvoient des éléments dans l'ordre dans lequel ils ont été ajoutés , plutôt que dans l'ordre cohérent basé sur le hachage utilisé pour les ensembles plus grands.

De plus, sameElements ( scaladoc ) est défini sur Iterables (il est implémenté dans IterableLike - voir source ) ; elle ne renvoie true que si les itérateurs renvoient les mêmes éléments dans le même ordre.

Ainsi, bien que Set(1,2,3) et Set(3,2,1) devraient être équivalents, leurs itérateurs sont différents, donc sameElements renvoie false.

Ce comportement est surprenant, et sans doute un bogue car il viole les attentes mathématiques pour un ensemble (mais seulement pour certaines tailles d'ensembles!).

Comme I.K. souligne dans les commentaires, == fonctionne bien si vous comparez simplement des ensembles les uns avec les autres, c'est-à-dire Set(1,2,3) == Set(3,2,1). Cependant, sameElements est plus général en ce sens qu'il peut comparer les éléments de deux itérables quelconques. Par exemple, List(1, 2, 3) == Array(1, 2, 3) est faux, mais List(1, 2, 3) sameElements Array(1, 2, 3) est vrai.

Plus généralement, l'égalité peut être source de confusion - notez que:

List(1,2,3) == Vector(1,2,3)
List(1,2,3) != Set(1,2,3)
List(1,2,3) != Array(1,2,3)      
Array(1,2,3) != Array(1,2,3)

J'ai soumis un correctif pour les exercices Scala qui explique le problème sameElements.

94
DNA