TL; DR:
Your operator is not transitive. Consider a = 0 , b = 0.6 , c = 1.2 with a tolerance of 1 . a==b , b==c , but a!=c . The solution is to split your values ββinto classes (e.g. rounding or truncating) and using Double.compare() to maintain transitivity.
My question is, is this lack of transitivity a real problem?
First, let's discuss whether your data is transitive when using fuzzyCompare(double, double, double) :
While in most cases your data will be transitive, you can create patterns that are not. Take the following values:
a = 384.52710054120 b = 384.52710054126 c = 384.52710054132
As you can see, using our new metric, the following is true: a==b , b==c , but a!=c As you can see, you have violated transitivity .
Is this a problem if your Comparator not transitive?
The methods state certain conditions using documentation and / or annotations. The compare promises method that the method is transitive. Breaking this promise can be justified in many cases, since transitivity is not important, but the code that builds on this promise may be broken.
What is sample code that might not work if the promise of transitivity is broken?
Allows you to create a script in which there are 3 elements of type Foo that are not transitive according to some Comparator called fooComparator . We call them f1 , f2 and f3 .
Comparator<Foo> fooComparator = new Comparator<Foo>(){ public int compare(Foo o1, Foo o2) {
Since they are not transitive, let f0 < f1 , f1 < f2 , f2 < f0 satisfied. What happens if you put them in a list and try sort() them?
List<Foo> foos = new LinkedList<>(); Collections.addAll(f1, f2, f3) Collections.sort(foos, fooComparator);
How to fix the problem
You can create a transitive operator by matching data with another data set and using the transit operator defined on this set. Allows you to compare real numbers with real numbers with less accuracy.
Consider the following values:
a = 0.01; b = 0.05; c = 0.13; d = 0.19; e = 0.21
If you truncate them to the second digit ( Math.truncate(x * 10)/10 ) and use Double.compare() , transitivity is preserved.
You can see that we put our values ββin three classes {a, b} < {c, d} < {e} . Undoubtedly, there is some important theorem which proves that this is so, but I cannot recall its name.