001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.utils;
022
023/**
024 * utility methods for implementing the equals() and hashCode() methods of Objects.
025 * All credit for this class goes to Mark Davis (Java Report 5(1), 46; Java Report 5(4), 60).
026 * <p>
027 * All equals() methods in this class take the two fields to compare for equality as arguments and return whether they
028 * are equal. Consequently, the equals() method of class AClass should be implemented (taking advantage of the equals() 
029 * methods in this class) as follows:
030 * <pre>
031 * public boolean equals(Object o) {
032 *   if (o == this) return true;
033 *   // if this class AClass is a direct sub-class of Object:
034 *   if (o == null) return false;
035 *   if (!o.getClass().equals(this.getClass())) return false;
036 *   // else if this class AClass extends another class than Object:
037 *   //if (!super.equals(o)) return false;
038 *   
039 *   AClass that = (AClass) o;
040 *   
041 *   // only compare fields of this class AClass (not of super-classes):
042 *   //if (!ObjectUtil.equals(this.field, that.field)) return false;
043 *   
044 *   // this and that are identical if we made it 'til here
045 *   return true;
046 * }
047 * </pre>
048 * <p>
049 * All hashCode() methods in this class take the current hashCode value as the first argument and the field to take into
050 * account as the second argument and return the newly calculated hashCode value (which now includes the influence of
051 * the given field). Consequently, the hashCode() method of class AClass should be implemented (taking advantage of the
052 * hashCode() methods in this class) as follows:
053 * <pre>
054 * public int hashCode() {
055 *   // if this class AClass is a direct sub-class of Object:
056 *   int hc = 0;
057 *   // else if this class AClass extends another class than Object:
058 *   //int hc = super.hashCode();
059 *
060 *   // only take into account fields of this class AClass (not of super-class):
061 *   //hc = ObjectUtil.hashCode(hc, field);
062 *
063 *   return hc;
064 * }
065 * </pre>
066 *
067 * @author <A href="mailto:Gerald.Loeffler@vienna.at">Gerald Loeffler</A>
068 */
069public final class ObjectUtil {
070  /**
071   * the current hashCode is always first multiplied with this prime before the hashCode value for a particular field is
072   * added.
073   */
074  public static final int PRIME = 1000003;
075
076  public static boolean equals(boolean b1, boolean b2) {
077    return b1 == b2;
078  }
079
080  public static boolean equals(int i1,  int i2) {
081    return i1 == i2;
082  }
083
084  public static boolean equals(long l1,  long l2) {
085    return l1 == l2;
086  }
087
088  public static boolean equals(float f1,  float f2) {
089    return ((Float.isNaN(f1) && Float.isNaN(f2)) || (f1 == f2));
090  }
091
092  public static boolean equals(double d1, double d2) {
093    return ((Double.isNaN(d1) && Double.isNaN(d2)) || (d1 == d2));
094  }
095
096  public static boolean equals(boolean[] a1, boolean[] a2) {
097    if (a1 == null && a2 == null) return true;
098    if (!(a1 != null && a2 != null)) return false;
099
100    final int l = a1.length;
101    if (l != a2.length) return false;
102
103    for (int i = 0; i < l; i++) {
104      if (!equals(a1[i], a2[i])) return false;
105    }
106    return true;
107  }
108
109  public static boolean equals(int[] a1, int[] a2) {
110    if (a1 == null && a2 == null) return true;
111    if (!(a1 != null && a2 != null)) return false;
112
113    final int l = a1.length;
114    if (l != a2.length) return false;
115
116    for (int i = 0; i < l; i++) {
117      if (!equals(a1[i], a2[i])) return false;
118    }
119    return true;
120  }
121
122  public static boolean equals(long[] a1, long[] a2) {
123    if (a1 == null && a2 == null) return true;
124    if (!(a1 != null && a2 != null)) return false;
125
126    final int l = a1.length;
127    if (l != a2.length) return false;
128
129    for (int i = 0; i < l; i++) {
130      if (!equals(a1[i], a2[i])) return false;
131    }
132    return true;
133  }
134
135  public static boolean equals(float[] a1, float[] a2) {
136    if (a1 == null && a2 == null) return true;
137    if (!(a1 != null && a2 != null)) return false;
138
139    final int l = a1.length;
140    if (l != a2.length) return false;
141
142    for (int i = 0; i < l; i++) {
143      if (!equals(a1[i], a2[i])) return false;
144    }
145    return true;
146  }
147
148  public static boolean equals(double[] a1, double[] a2) {
149    if (a1 == null && a2 == null) return true;
150    if (!(a1 != null && a2 != null)) return false;
151
152    final int l = a1.length;
153    if (l != a2.length) return false;
154
155    for (int i = 0; i < l; i++) {
156      if (!equals(a1[i], a2[i])) return false;
157    }
158    return true;
159  }
160
161  public static boolean equals(Object[] a1, Object[] a2) {
162    if (a1 == null && a2 == null) return true;
163    if (!(a1 != null && a2 != null)) return false;
164
165    final int l = a1.length;
166    if (l != a2.length) return false;
167
168    for (int i = 0; i < l; i++) {
169      if (!equals(a1[i], a2[i])) return false;
170    }
171    return true;
172  }
173
174  public static boolean equals(Object o1, Object o2) {
175    return ((o1 == null && o2 == null) || (o1 != null && o1.equals(o2)) || (o2 != null && o2.equals(o1)));
176  }
177
178  public static int hashCode(int currentHashCodeValue, boolean b) {
179    return PRIME*currentHashCodeValue + (b ? 1 : 0);
180  }
181
182  public static int hashCode(int currentHashCodeValue, int i) {
183    return PRIME*currentHashCodeValue + i;
184  }
185
186  public static int hashCode(int currentHashCodeValue, long l) {
187    return PRIME*(PRIME*currentHashCodeValue + ((int) (l>>>32))) + ((int) (l&0xFFFFFFFF));
188  }
189
190  public static int hashCode(int currentHashCodeValue, float f) {
191    return hashCode(currentHashCodeValue, f == 0.0F ? 0 : Float.floatToIntBits(f));
192  }
193
194  public static int hashCode(int currentHashCodeValue, double d) {
195    return hashCode(currentHashCodeValue, d == 0.0 ? 0L : Double.doubleToLongBits(d));
196  }
197
198  public static int hashCode(int currentHashCodeValue, boolean[] a) {
199    if (a == null) return PRIME*currentHashCodeValue;
200    
201    final int l = a.length;
202    for (int i = 0; i < l; i++) {
203      currentHashCodeValue = hashCode(currentHashCodeValue, a[i]);
204    }
205    return currentHashCodeValue;
206  }
207
208  public static int hashCode(int currentHashCodeValue, int[] a) {
209    if (a == null) return PRIME*currentHashCodeValue;
210    
211    final int l = a.length;
212    for (int i = 0; i < l; i++) {
213      currentHashCodeValue = hashCode(currentHashCodeValue, a[i]);
214    }
215    return currentHashCodeValue;
216  }
217
218  public static int hashCode(int currentHashCodeValue, long[] a) {
219    if (a == null) return PRIME*currentHashCodeValue;
220    
221    final int l = a.length;
222    for (int i = 0; i < l; i++) {
223      currentHashCodeValue = hashCode(currentHashCodeValue, a[i]);
224    }
225    return currentHashCodeValue;
226  }
227
228  public static int hashCode(int currentHashCodeValue, float[] a) {
229    if (a == null) return PRIME*currentHashCodeValue;
230    
231    final int l = a.length;
232    for (int i = 0; i < l; i++) {
233      currentHashCodeValue = hashCode(currentHashCodeValue, a[i]);
234    }
235    return currentHashCodeValue;
236  }
237
238  public static int hashCode(int currentHashCodeValue, double[] a) {
239    if (a == null) return PRIME*currentHashCodeValue;
240    
241    final int l = a.length;
242    for (int i = 0; i < l; i++) {
243      currentHashCodeValue = hashCode(currentHashCodeValue, a[i]);
244    }
245    return currentHashCodeValue;
246  }
247
248  public static int hashCode(int currentHashCodeValue, Object[] a) {
249    if (a == null) return PRIME*currentHashCodeValue;
250    
251    final int l = a.length;
252    for (int i = 0; i < l; i++) {
253      currentHashCodeValue = hashCode(currentHashCodeValue, a[i]);
254    }
255    return currentHashCodeValue;
256  }
257
258  public static int hashCode(int currentHashCodeValue, Object o) {
259    return PRIME*currentHashCodeValue + (o == null ? 0 : o.hashCode());
260  }
261}