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
>