Example:Java .equals and .hashCode
Many programming languages allow you to redefine the notion of `.equals` for objects of different types. For example, Java lets you to override the `.equals` function for comparing objects, Python lets you write a `__eq__` function, OCaml lets you define `(=)`.
When you redefine equality for a new type, you are really saying that you want to think of objects of that type as equivalence classes of objects. I might represent the set as the array `[x,y,z]` or as the array `[y,z,x]` (or possibly even as the array `[x,x,y,z,y]`, depending on my implementation). But as a user, I want to think of all of these as different representatives of the same object: the set itself is in some sense the equivalence class containing those different representations.
For example, the Java specification requires you to redefine a function called `.hashCode` whenever you redefine `.equals`. The reason for this is that it might no longer be a well-defined function if two different objects are in the same equivalence class.
`.hashCode` is used to look up objects in some data structures. For example, it might be the case that `[1,2,3].hashCode() = 17` but `[3,1,2].hashCode() = 5`, meaning that `[1,2,3]` should be stored in slot 17 and `[3,1,2]` should be stored in slot 5. That's not a problem if `[1,2,3]` and `[3,1,2]` are different objects, but if we are thinking of them both as representatives of the set , then the set might end up in two different places in our data structure, causing it to behave incorrectly.