Implement #? manually on a class that combines multiple fields.
← Operators and Expressions · Ref: Q1053
Combine the hash values of each field using arithmetic. The #? prefix operator gets the hash of individual fields.
operator #? as pure <- rtn as Integer: #?firstName + #?lastName + #?age
Each #?field calls _hashcode() on that field. Adding them produces a combined hash. For better distribution, multiply by a prime:
operator #? as pure <- rtn as Integer: (#?firstName * 31) + (#?lastName * 17) + #?age
Alternatively, use 'default operator' to auto-generate #? from all fields. Manual implementation is only needed when you want a custom hash strategy (for example, hashing on a subset of fields).
The #? operator must be pure, take no parameters, and return Integer.
See Q911 for what #? means. See Q1047 for #? on records with default operator. See Q1055 for default vs manual operators.
Example
defines module qa.operators.hashcodeclassmulti defines class Employee firstName as String: String() lastName as String: String() employeeId as Integer: 0 default private Employee() Employee() -> firstName as String lastName as String employeeId as Integer this.firstName :=: firstName this.lastName :=: lastName this.employeeId :=: employeeId //Custom #? using subset of fields operator #? as pure <- rtn as Integer: (#?firstName * 31) + (#?lastName * 17) + #?employeeId operator == as pure -> other as Employee <- rtn as Boolean: employeeId == other.employeeId override operator ? as pure <- rtn as Boolean: firstName? and lastName? and employeeId? operator $ as pure <- rtn as String: `${firstName} ${lastName} (${employeeId})` defines program HashcodeClassDemo() stdout <- Stdout() emp1 <- Employee("Alice", "Smith", 1001) emp2 <- Employee("Alice", "Smith", 1001) emp3 <- Employee("Bob", "Jones", 1002) stdout.println(`emp1 hash: ${#? emp1}`) stdout.println(`emp2 hash: ${#? emp2}`) stdout.println(`emp3 hash: ${#? emp3}`) stdout.println(`emp1 == emp2: ${emp1 == emp2}`)
Common mistakes
E07550 — The #? operator must return Integer. Using Float or any other type triggers E07550.
Incorrect:
operator #? as pure <- rtn as Float: #?firstName + #?lastName
Correct:
operator #? as pure <- rtn as Integer: (#?firstName * 31) + (#?lastName * 17) + #?employeeId
Other ways to ask this
- Write a custom hashcode operator for a class with several fields
- How do I build a hashcode from multiple fields in EK9?
- Show me a multi-field #? implementation on a class
Coming from another language?
Java: Objects.hash(field1, field2). Python: hash((f1, f2)). EK9: #?field1 + #?field2 or 'default operator'.
Keywords: hashcode, operator, class, manual, multi-field, custom