I have a class with a float field. For example:
public class MultipleFields {
  final int   count;
  final float floatValue;
  public MultipleFields(int count, float floatValue) {
    this.count = count;
    this.floatValue = floatValue;
  }
}
I need to be able to compare instances by value.  Now how do I properly implement  equals & hashCode?
The usual way to implement equals and hashCode is to just consider all fields. E.g. Eclipse will generate the following equals:
  public boolean equals(Object obj) {
    // irrelevant type checks removed
    ....
    MultipleFields other = (MultipleFields) obj;
    if (count != other.count)
      return false;
    if (Float.floatToIntBits(floatValue) != Float.floatToIntBits(other.floatValue))
      return false;
    return true;
  }
(and a similar hashCode, that essentially computes count* 31 + Float.floatToIntBits(floatValue)).
The problem with this is that my FP values are subject to rounding errors (they may come from user input, from a DB, etc.). So I need a "tolerant" comparison.
The common solution is to compare using an epsilon value (see e.g. Comparing IEEE floats and doubles for equality). However, I'm not quite certain how I can implement equals using this method, and still have a hashCode that is consisten with equals. 
My idea is to define the number of significant digits for comparison, then always round to that number of digits in both equals and hashCode:
long comparisonFloatValue = Math.round(floatValue* (Math.pow(10, RELEVANT_DIGITS)));
Then if I replace all uses of floatValue with comparisonFloatValue in  equals and hashCode, I should get a "tolerant" comparison, which is consistent with hashCode.
- Will this work?
- Do you see any problems with this approach?
- Is there a better way to do this? It seems rather complicated.
 
     
    