| <?xml version="1.0" encoding="UTF-8" ?> |
| <!DOCTYPE html> |
| |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| --> |
| |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> |
| <head> |
| <title>ComparisonModes</title> |
| <meta charset="UTF-8"/> |
| <link rel="stylesheet" type="text/css" href="../book.css"/> |
| </head> |
| <body> |
| <!-- |
| Content below this point is copied in "/asf-staging/book/en/developer-guide.html" file |
| by the `org.apache.sis.buildtools.book` class in `buildSrc`. |
| --> |
| <section> |
| <header> |
| <h2 id="ComparisonModes">Comparison modes of objects</h2> |
| </header> |
| <p> |
| There are various opinions on how to implement Java standard’s <code>Object.equals(Object)</code> method. |
| According to some, it should be possible to compare different implementations of the same interface or base class. |
| But to follow this policy, each interface or base class’s javadoc must define the algorithms that all implementations |
| shall use for their <code>equals(Object)</code> and <code>hashCode()</code> methods. |
| This approach is common in <code>java.util.Collection</code> and its child interfaces. |
| Transferring this approach to certain GeoAPI interfaces, however, would be a difficult task, |
| and would probably not be followed in many implementations. |
| Moreover, it comes at the expense of being able to take into account supplementary attributes in the child interfaces, |
| unless this possibility has been specified in the parent interface. |
| This constraint arises from the following points of the <code>equals(Object)</code> and <code>hashCode()</code> method contracts: |
| </p> |
| <ul> |
| <li><code>A.equals(B)</code> implies <code>B.equals(A)</code> (symmetry);</li> |
| <li><code>A.equals(B)</code> and <code>B.equals(C)</code> implies <code>A.equals(C)</code> (transitivity);</li> |
| <li><code>A.equals(B)</code> implies <code>A.hashCode() == B.hashCode()</code>.</li> |
| </ul> |
| <p> |
| For example, these three constraints are violated if <var>A</var> (and eventually <var>C</var>) can contain attributes |
| which <var>B</var> ignores. |
| To bypass this problem, an alternative approach is to require that the objects compared by the |
| <code>Object.equals(Object)</code> method be of the same class; in other words, <code>A.getClass() == B.getClass()</code>. |
| This approach is sometimes regarded as contrary to the principles of object oriented programming. |
| In practice, for relatively complex applications, the important accorded to these principles depends on the context |
| in which the objects are compared: |
| if the objects are added to a <code>HashSet</code> or used as keys in a <code>HashMap</code>, |
| we would need a stricter adherence to the <code>equals(Object)</code> and <code>hashCode()</code> contract. |
| But if the developer is comparing the objects his- or herself, for example to check that the relevant information has been changed, |
| then the constraints of symmetry, transitivity or coherence with the hash values may be of little interest. |
| More permissive comparisons may be desirable, sometimes going so far as to tolerate minor discrepancies in numerical values. |
| </p> |
| <p> |
| In order to allow developers a certain amount of flexibility, many classes in the <abbr>SIS</abbr> |
| library implement the <code>org.apache.sis.util.LenientComparable</code> interface, |
| which defines a <code class="SIS">equals(Object, ComparisonMode)</code> method. |
| The principle modes of comparison are: |
| </p> |
| <ul> |
| <li><p> |
| <b><code class="SIS">STRICT</code></b> — The objects compared must share the same class and have exactly equal attributes, |
| including any possible public attributes specific to the implementation. |
| </p></li> |
| <li><p> |
| <b><code class="SIS">BY_CONTRACT</code></b> — The objects compared must implement the same GeoAPI (or other standard) |
| interface, but need not be of the same implementation class. |
| Only the attributes defined in the interface are compared; |
| all other attributes specific to the implementation — even if they are public — are ignored. |
| </p></li> |
| <li><p> |
| <b><code class="SIS">IGNORE_METADATA</code></b> — Like <code class="SIS">BY_CONTRACT</code>, |
| but only compares attributes that influence the operations (numeric calculations or otherwise) performed by the object. |
| For example, in a geodesic datum, the longitude (in relation to Greenwich) of the original meridian |
| would be taken into account, while the name of the meridian would be ignored. |
| </p></li> |
| <li><p> |
| <b><code class="SIS">APPROXIMATIVE</code></b> — Like <code class="SIS">IGNORE_METADATA</code>, |
| but tolerates minor discrepancies in numerical values. |
| </p></li> |
| </ul> |
| <p> |
| The default mode, used in all <code>equals(Object)</code> methods in <abbr>SIS</abbr>, |
| is <code class="SIS">STRICT</code>. This mode is chosen for a safe operation — particularly with <code>HashMap</code> — |
| without the need to rigorously define <code>equals(Object)</code> and <code>hashCode()</code> operations in every interface. |
| With this mode, the order of objects (<code>A.equals(B)</code> or <code>B.equals(A)</code>) is unimportant. |
| It is, however, the only mode that offers this guarantee. |
| In the expression <code>A.equals(B)</code>, the <code class="SIS">BY_CONTRACT</code> mode |
| (and so by extension all other modes that depend on it) only compares the properties known to <code>A</code>, |
| regardless of whether <code>B</code> knows more. |
| </p> |
| </section> |
| </body> |
| </html> |