You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sis.apache.org by Martin Desruisseaux <ma...@geomatys.fr> on 2012/10/18 15:49:36 UTC
Comparison modes
Hello all
Still following the chain of dependencies needed before I can commit
metadata, I just committed a LenientComparable interface (suggestions
for better name welcome) together with its related ComparisonMode enum.
This interface defines the following method:
boolean equals(Object, ComparisonMode);
There is different opinions about how to properly implement
Object.equals(Object). Some said that we need to accept any
implementations of the interface. But this requires the interface
Javadoc to specify how every implementations shall implement equals and
hashCode. This is what Java collections do.
An other approach is to accept only objects of the exact same class.
This approach provides more guarantees that the 'equals' contract is
respected:
* A.equals(B) implies B.equals(A);
* A.equals(B) & B.equals(C) implies A.equals(C);
* A.equals(B) implies A.hashCode() == B.hashCode();
The above conditions are easily broken when mixing implementations.
GeoAPI provides hundred of interfaces. To specify 'equals' and
'hashCode' contract in every interfaces would be a very big task, and
unlikely (in my opinion) to be followed by all implementations. So the
proposed approach is to make 'equals(Object)' strict - for safer use in
HashMap - and allow user to perform more lenient comparisons only when
requested.
The comparison modes are:
STRICT - objects of the same class and all properties strictly equal.
This is the default mode of equals(Object).
BY_CONTRACT - objects implementing the same interface (not necessarily
of the same class), and only properties defined in the interface (by
getter methods) are compared.
IGNORE_METADATA - This is used mostly for coordinate transformations.
Basically, only the mathematical formulas is compared. Information like
the projection name, which have no incidence on the actual coordinate
valures, are ignored.
APPROXIMATIVE - tolerate slight rounding errors when comparing objects.
DEBUG - When two objects are expected to be equal but are not, it may be
very difficult to find which property is different because the tree may
be very depth. When two objects are not equal, this special comparison
mode throws an AssertionError with more detailed information about the
faulty property.
Is there any comment, or things that I should change?
Martin
Re: Comparison modes
Posted by "Mattmann, Chris A (388J)" <ch...@jpl.nasa.gov>.
Hi Martin,
This makes sense to me. Better to handle the implementation in a concrete, superclass. You are using the parent of them all, which makes sense
since we are dealing with Java interfaces, and we don't want to amortize the development costs of our downstream API implementers by asking
them to implement these methods.
+1 to all of your suggestions below.
Thanks!
Cheers,
Chris
On Oct 18, 2012, at 6:49 AM, Martin Desruisseaux wrote:
> Hello all
>
> Still following the chain of dependencies needed before I can commit metadata, I just committed a LenientComparable interface (suggestions for better name welcome) together with its related ComparisonMode enum. This interface defines the following method:
>
> boolean equals(Object, ComparisonMode);
>
> There is different opinions about how to properly implement Object.equals(Object). Some said that we need to accept any implementations of the interface. But this requires the interface Javadoc to specify how every implementations shall implement equals and hashCode. This is what Java collections do.
>
> An other approach is to accept only objects of the exact same class. This approach provides more guarantees that the 'equals' contract is respected:
>
> * A.equals(B) implies B.equals(A);
> * A.equals(B) & B.equals(C) implies A.equals(C);
> * A.equals(B) implies A.hashCode() == B.hashCode();
>
> The above conditions are easily broken when mixing implementations.
>
> GeoAPI provides hundred of interfaces. To specify 'equals' and 'hashCode' contract in every interfaces would be a very big task, and unlikely (in my opinion) to be followed by all implementations. So the proposed approach is to make 'equals(Object)' strict - for safer use in HashMap - and allow user to perform more lenient comparisons only when requested.
>
> The comparison modes are:
>
> STRICT - objects of the same class and all properties strictly equal. This is the default mode of equals(Object).
>
> BY_CONTRACT - objects implementing the same interface (not necessarily of the same class), and only properties defined in the interface (by getter methods) are compared.
>
> IGNORE_METADATA - This is used mostly for coordinate transformations. Basically, only the mathematical formulas is compared. Information like the projection name, which have no incidence on the actual coordinate valures, are ignored.
>
> APPROXIMATIVE - tolerate slight rounding errors when comparing objects.
>
> DEBUG - When two objects are expected to be equal but are not, it may be very difficult to find which property is different because the tree may be very depth. When two objects are not equal, this special comparison mode throws an AssertionError with more detailed information about the faulty property.
>
>
> Is there any comment, or things that I should change?
>
> Martin
>