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}