Primitive double comparisons and Double wrapper equality use different rules for NaN and signed zero.
Java Double NaN and signed zero: primitive and wrapper comparisons differ
Know which equality a collection uses
At the primitive level NaN is unequal to itself, while Double.equals treats canonical NaN values as equal. A HashSet of boxed doubles therefore holds one NaN key. Signed positive and negative zero compare equal with ==, but Double.equals distinguishes them. This matters for keyed metrics and deduplication.
The fixture prints both cases. Finite-value validation can reject NaN before it reaches a map or arithmetic pipeline when the domain has no meaning for it.
Define a metric-key policy
If zero signs should collapse, normalize them before using Double as a key. If NaN is invalid input, reject it rather than relying on wrapper equality. A comparator and equals policy must also agree with the collection being used.
Working program
import java.util.HashSet;
import java.util.Set;
public class SensorReadingIdentity {
public static void main(String[] args) {
double missingReading = Double.NaN;
System.out.println("primitive NaN=" + (missingReading == missingReading));
Set<Double> unique = new HashSet<>();
unique.add(Double.NaN);
unique.add(Double.NaN);
System.out.println("boxed NaN count=" + unique.size());
System.out.println("primitive zero=" + (-0.0 == 0.0));
System.out.println("boxed zero=" + Double.valueOf(-0.0).equals(0.0));
}
}Output
primitive NaN=false
boxed NaN count=1
primitive zero=true
boxed zero=falseCost and ownership
Each comparison is constant work. HashSet adds storage for boxed keys, and its identity semantics follow Double.equals rather than primitive ==. The correct policy depends on whether signed zero and NaN carry domain meaning.
Common Mistakes
- Do not assume boxed Double equality matches primitive == for NaN or signed zero.
- Do not store NaN as a normal measurement if the domain requires finite values.
- Do not use floating-point keys without defining normalization.
Read next
double finite validation, Java HashSet: deduplication and equality, Java comparators: tie-breakers, overflow and sorted-key identity, floating sum order.
