4

Or does Scala compute tuple hashcode using something independent of its elements, like memory address?

In other words, given two Tuple2s (a, b) and (c, d), does a == c && b == d imply (a, b).hashCode == (c, d).hashCode?

Fermat's Little Student
  • 5,549
  • 7
  • 49
  • 70

2 Answers2

7

does a == c && b == d imply (a, b).hashCode == (c, d).hashCode?

Yes, it does. This is the contract between == and hashCode. (*)

Does Scala tuple type uses all of its elements to compute its hash code?

Yes, it does. Scala Tuple2 is just a case class:

final case class Tuple2[@specialized(Int, Long, Double, Char, Boolean/*, AnyRef*/) +T1, @specialized(Int, Long, Double, Char, Boolean/*, AnyRef*/) +T2](_1: T1, _2: T2)
  extends Product2[T1, T2]
{
 ...
}

In Scala hashCode for a case class is calculated in the following way:

hashCode in case classes in Scala

What code is generated for an equals/hashCode method of a case class?


(*) From the following it can be seen that for case classes (including tuples) the contract is fulfilled.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
  • So comparing `Map[(A, B), C]` with `Map[A, Map[B, C]]`, which one is better in term of querying performance? – Fermat's Little Student Sep 19 '17 at 18:34
  • 2
    *This is the contract between == and hashCode* Although that is the *requirement* (in general) from overriding `hashCode` and `equals`, there is no guarantee this will exist in reality, so you better verify. Perhaps it's worth mentioning in the answer. – Yuval Itzchakov Sep 19 '17 at 18:35
  • @Will That really depends on the usecase. If you're looking up values by key, like you should when working with a `Map`, performance differences between the two should be negligible IMO as long as `A` has a "good" implementation of `equals` and `hashCode`, which is up to you to guarantee. Also, you might need to take into account that you'll need to look up the additional `Map` which serves as the value of `A`, which might add to the total time. All in all, use JMH to micro benchmark. – Yuval Itzchakov Sep 19 '17 at 18:36
  • @Will in such formulation the question is pointless. `Map` is just a trait, every its implementation can have its own behavior. Probable you asked about `HashMap`. Refer @Yuval's comment. – Dmytro Mitin Sep 19 '17 at 18:43
  • @YuvalItzchakov Thanks, slightly updated the answer. – Dmytro Mitin Sep 19 '17 at 18:45
3

Scala tuples (and case classes for that matter) implement hashCode and == based on all of their contents and nothing else.

So yes, a == c && b == d implies (a, b).hashCode == (c, d).hashCode, assuming the hashCode methods for a, b, c, and d are also well-behaved.

Joe K
  • 18,204
  • 2
  • 36
  • 58