001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.lang3.builder; 019 020import java.lang.reflect.AccessibleObject; 021import java.lang.reflect.Field; 022import java.lang.reflect.Modifier; 023import java.util.Collection; 024import java.util.HashSet; 025import java.util.Set; 026 027import org.apache.commons.lang3.ArrayUtils; 028import org.apache.commons.lang3.Validate; 029 030/** 031 * <p> 032 * Assists in implementing {@link Object#hashCode()} methods. 033 * </p> 034 * 035 * <p> 036 * This class enables a good <code>hashCode</code> method to be built for any class. It follows the rules laid out in 037 * the book <a href="http://www.oracle.com/technetwork/java/effectivejava-136174.html">Effective Java</a> by Joshua Bloch. Writing a 038 * good <code>hashCode</code> method is actually quite difficult. This class aims to simplify the process. 039 * </p> 040 * 041 * <p> 042 * The following is the approach taken. When appending a data field, the current total is multiplied by the 043 * multiplier then a relevant value 044 * for that data type is added. For example, if the current hashCode is 17, and the multiplier is 37, then 045 * appending the integer 45 will create a hash code of 674, namely 17 * 37 + 45. 046 * </p> 047 * 048 * <p> 049 * All relevant fields from the object should be included in the <code>hashCode</code> method. Derived fields may be 050 * excluded. In general, any field used in the <code>equals</code> method must be used in the <code>hashCode</code> 051 * method. 052 * </p> 053 * 054 * <p> 055 * To use this class write code as follows: 056 * </p> 057 * 058 * <pre> 059 * public class Person { 060 * String name; 061 * int age; 062 * boolean smoker; 063 * ... 064 * 065 * public int hashCode() { 066 * // you pick a hard-coded, randomly chosen, non-zero, odd number 067 * // ideally different for each class 068 * return new HashCodeBuilder(17, 37). 069 * append(name). 070 * append(age). 071 * append(smoker). 072 * toHashCode(); 073 * } 074 * } 075 * </pre> 076 * 077 * <p> 078 * If required, the superclass <code>hashCode()</code> can be added using {@link #appendSuper}. 079 * </p> 080 * 081 * <p> 082 * Alternatively, there is a method that uses reflection to determine the fields to test. Because these fields are 083 * usually private, the method, <code>reflectionHashCode</code>, uses <code>AccessibleObject.setAccessible</code> 084 * to change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions 085 * are set up correctly. It is also slower than testing explicitly. 086 * </p> 087 * 088 * <p> 089 * A typical invocation for this method would look like: 090 * </p> 091 * 092 * <pre> 093 * public int hashCode() { 094 * return HashCodeBuilder.reflectionHashCode(this); 095 * } 096 * </pre> 097 * 098 * <p>The {@link HashCodeExclude} annotation can be used to exclude fields from being 099 * used by the <code>reflectionHashCode</code> methods.</p> 100 * 101 * @since 1.0 102 */ 103public class HashCodeBuilder implements Builder<Integer> { 104 /** 105 * The default initial value to use in reflection hash code building. 106 */ 107 private static final int DEFAULT_INITIAL_VALUE = 17; 108 109 /** 110 * The default multiplier value to use in reflection hash code building. 111 */ 112 private static final int DEFAULT_MULTIPLIER_VALUE = 37; 113 114 /** 115 * <p> 116 * A registry of objects used by reflection methods to detect cyclical object references and avoid infinite loops. 117 * </p> 118 * 119 * @since 2.3 120 */ 121 private static final ThreadLocal<Set<IDKey>> REGISTRY = new ThreadLocal<>(); 122 123 /* 124 * NOTE: we cannot store the actual objects in a HashSet, as that would use the very hashCode() 125 * we are in the process of calculating. 126 * 127 * So we generate a one-to-one mapping from the original object to a new object. 128 * 129 * Now HashSet uses equals() to determine if two elements with the same hash code really 130 * are equal, so we also need to ensure that the replacement objects are only equal 131 * if the original objects are identical. 132 * 133 * The original implementation (2.4 and before) used the System.identityHashCode() 134 * method - however this is not guaranteed to generate unique ids (e.g. LANG-459) 135 * 136 * We now use the IDKey helper class (adapted from org.apache.axis.utils.IDKey) 137 * to disambiguate the duplicate ids. 138 */ 139 140 /** 141 * <p> 142 * Returns the registry of objects being traversed by the reflection methods in the current thread. 143 * </p> 144 * 145 * @return Set the registry of objects being traversed 146 * @since 2.3 147 */ 148 static Set<IDKey> getRegistry() { 149 return REGISTRY.get(); 150 } 151 152 /** 153 * <p> 154 * Returns <code>true</code> if the registry contains the given object. Used by the reflection methods to avoid 155 * infinite loops. 156 * </p> 157 * 158 * @param value 159 * The object to lookup in the registry. 160 * @return boolean <code>true</code> if the registry contains the given object. 161 * @since 2.3 162 */ 163 static boolean isRegistered(final Object value) { 164 final Set<IDKey> registry = getRegistry(); 165 return registry != null && registry.contains(new IDKey(value)); 166 } 167 168 /** 169 * <p> 170 * Appends the fields and values defined by the given object of the given <code>Class</code>. 171 * </p> 172 * 173 * @param object 174 * the object to append details of 175 * @param clazz 176 * the class to append details of 177 * @param builder 178 * the builder to append to 179 * @param useTransients 180 * whether to use transient fields 181 * @param excludeFields 182 * Collection of String field names to exclude from use in calculation of hash code 183 */ 184 private static void reflectionAppend(final Object object, final Class<?> clazz, final HashCodeBuilder builder, final boolean useTransients, 185 final String[] excludeFields) { 186 if (isRegistered(object)) { 187 return; 188 } 189 try { 190 register(object); 191 final Field[] fields = clazz.getDeclaredFields(); 192 AccessibleObject.setAccessible(fields, true); 193 for (final Field field : fields) { 194 if (!ArrayUtils.contains(excludeFields, field.getName()) 195 && !field.getName().contains("$") 196 && (useTransients || !Modifier.isTransient(field.getModifiers())) 197 && !Modifier.isStatic(field.getModifiers()) 198 && !field.isAnnotationPresent(HashCodeExclude.class)) { 199 try { 200 final Object fieldValue = field.get(object); 201 builder.append(fieldValue); 202 } catch (final IllegalAccessException e) { 203 // this can't happen. Would get a Security exception instead 204 // throw a runtime exception in case the impossible happens. 205 throw new InternalError("Unexpected IllegalAccessException"); 206 } 207 } 208 } 209 } finally { 210 unregister(object); 211 } 212 } 213 214 /** 215 * <p> 216 * Uses reflection to build a valid hash code from the fields of {@code object}. 217 * </p> 218 * 219 * <p> 220 * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will 221 * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is 222 * also not as efficient as testing explicitly. 223 * </p> 224 * 225 * <p> 226 * Transient members will be not be used, as they are likely derived fields, and not part of the value of the 227 * <code>Object</code>. 228 * </p> 229 * 230 * <p> 231 * Static fields will not be tested. Superclass fields will be included. 232 * </p> 233 * 234 * <p> 235 * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class, 236 * however this is not vital. Prime numbers are preferred, especially for the multiplier. 237 * </p> 238 * 239 * @param initialNonZeroOddNumber 240 * a non-zero, odd number used as the initial value. This will be the returned 241 * value if no fields are found to include in the hash code 242 * @param multiplierNonZeroOddNumber 243 * a non-zero, odd number used as the multiplier 244 * @param object 245 * the Object to create a <code>hashCode</code> for 246 * @return int hash code 247 * @throws IllegalArgumentException 248 * if the Object is <code>null</code> 249 * @throws IllegalArgumentException 250 * if the number is zero or even 251 * 252 * @see HashCodeExclude 253 */ 254 public static int reflectionHashCode(final int initialNonZeroOddNumber, final int multiplierNonZeroOddNumber, final Object object) { 255 return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null); 256 } 257 258 /** 259 * <p> 260 * Uses reflection to build a valid hash code from the fields of {@code object}. 261 * </p> 262 * 263 * <p> 264 * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will 265 * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is 266 * also not as efficient as testing explicitly. 267 * </p> 268 * 269 * <p> 270 * If the TestTransients parameter is set to <code>true</code>, transient members will be tested, otherwise they 271 * are ignored, as they are likely derived fields, and not part of the value of the <code>Object</code>. 272 * </p> 273 * 274 * <p> 275 * Static fields will not be tested. Superclass fields will be included. 276 * </p> 277 * 278 * <p> 279 * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class, 280 * however this is not vital. Prime numbers are preferred, especially for the multiplier. 281 * </p> 282 * 283 * @param initialNonZeroOddNumber 284 * a non-zero, odd number used as the initial value. This will be the returned 285 * value if no fields are found to include in the hash code 286 * @param multiplierNonZeroOddNumber 287 * a non-zero, odd number used as the multiplier 288 * @param object 289 * the Object to create a <code>hashCode</code> for 290 * @param testTransients 291 * whether to include transient fields 292 * @return int hash code 293 * @throws IllegalArgumentException 294 * if the Object is <code>null</code> 295 * @throws IllegalArgumentException 296 * if the number is zero or even 297 * 298 * @see HashCodeExclude 299 */ 300 public static int reflectionHashCode(final int initialNonZeroOddNumber, final int multiplierNonZeroOddNumber, final Object object, 301 final boolean testTransients) { 302 return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null); 303 } 304 305 /** 306 * <p> 307 * Uses reflection to build a valid hash code from the fields of {@code object}. 308 * </p> 309 * 310 * <p> 311 * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will 312 * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is 313 * also not as efficient as testing explicitly. 314 * </p> 315 * 316 * <p> 317 * If the TestTransients parameter is set to <code>true</code>, transient members will be tested, otherwise they 318 * are ignored, as they are likely derived fields, and not part of the value of the <code>Object</code>. 319 * </p> 320 * 321 * <p> 322 * Static fields will not be included. Superclass fields will be included up to and including the specified 323 * superclass. A null superclass is treated as java.lang.Object. 324 * </p> 325 * 326 * <p> 327 * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class, 328 * however this is not vital. Prime numbers are preferred, especially for the multiplier. 329 * </p> 330 * 331 * @param <T> 332 * the type of the object involved 333 * @param initialNonZeroOddNumber 334 * a non-zero, odd number used as the initial value. This will be the returned 335 * value if no fields are found to include in the hash code 336 * @param multiplierNonZeroOddNumber 337 * a non-zero, odd number used as the multiplier 338 * @param object 339 * the Object to create a <code>hashCode</code> for 340 * @param testTransients 341 * whether to include transient fields 342 * @param reflectUpToClass 343 * the superclass to reflect up to (inclusive), may be <code>null</code> 344 * @param excludeFields 345 * array of field names to exclude from use in calculation of hash code 346 * @return int hash code 347 * @throws IllegalArgumentException 348 * if the Object is <code>null</code> 349 * @throws IllegalArgumentException 350 * if the number is zero or even 351 * 352 * @see HashCodeExclude 353 * @since 2.0 354 */ 355 public static <T> int reflectionHashCode(final int initialNonZeroOddNumber, final int multiplierNonZeroOddNumber, final T object, 356 final boolean testTransients, final Class<? super T> reflectUpToClass, final String... excludeFields) { 357 Validate.isTrue(object != null, "The object to build a hash code for must not be null"); 358 final HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber); 359 Class<?> clazz = object.getClass(); 360 reflectionAppend(object, clazz, builder, testTransients, excludeFields); 361 while (clazz.getSuperclass() != null && clazz != reflectUpToClass) { 362 clazz = clazz.getSuperclass(); 363 reflectionAppend(object, clazz, builder, testTransients, excludeFields); 364 } 365 return builder.toHashCode(); 366 } 367 368 /** 369 * <p> 370 * Uses reflection to build a valid hash code from the fields of {@code object}. 371 * </p> 372 * 373 * <p> 374 * This constructor uses two hard coded choices for the constants needed to build a hash code. 375 * </p> 376 * 377 * <p> 378 * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will 379 * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is 380 * also not as efficient as testing explicitly. 381 * </p> 382 * 383 * <P> 384 * If the TestTransients parameter is set to <code>true</code>, transient members will be tested, otherwise they 385 * are ignored, as they are likely derived fields, and not part of the value of the <code>Object</code>. 386 * </p> 387 * 388 * <p> 389 * Static fields will not be tested. Superclass fields will be included. If no fields are found to include 390 * in the hash code, the result of this method will be constant. 391 * </p> 392 * 393 * @param object 394 * the Object to create a <code>hashCode</code> for 395 * @param testTransients 396 * whether to include transient fields 397 * @return int hash code 398 * @throws IllegalArgumentException 399 * if the object is <code>null</code> 400 * 401 * @see HashCodeExclude 402 */ 403 public static int reflectionHashCode(final Object object, final boolean testTransients) { 404 return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, 405 testTransients, null); 406 } 407 408 /** 409 * <p> 410 * Uses reflection to build a valid hash code from the fields of {@code object}. 411 * </p> 412 * 413 * <p> 414 * This constructor uses two hard coded choices for the constants needed to build a hash code. 415 * </p> 416 * 417 * <p> 418 * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will 419 * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is 420 * also not as efficient as testing explicitly. 421 * </p> 422 * 423 * <p> 424 * Transient members will be not be used, as they are likely derived fields, and not part of the value of the 425 * <code>Object</code>. 426 * </p> 427 * 428 * <p> 429 * Static fields will not be tested. Superclass fields will be included. If no fields are found to include 430 * in the hash code, the result of this method will be constant. 431 * </p> 432 * 433 * @param object 434 * the Object to create a <code>hashCode</code> for 435 * @param excludeFields 436 * Collection of String field names to exclude from use in calculation of hash code 437 * @return int hash code 438 * @throws IllegalArgumentException 439 * if the object is <code>null</code> 440 * 441 * @see HashCodeExclude 442 */ 443 public static int reflectionHashCode(final Object object, final Collection<String> excludeFields) { 444 return reflectionHashCode(object, ReflectionToStringBuilder.toNoNullStringArray(excludeFields)); 445 } 446 447 // ------------------------------------------------------------------------- 448 449 /** 450 * <p> 451 * Uses reflection to build a valid hash code from the fields of {@code object}. 452 * </p> 453 * 454 * <p> 455 * This constructor uses two hard coded choices for the constants needed to build a hash code. 456 * </p> 457 * 458 * <p> 459 * It uses <code>AccessibleObject.setAccessible</code> to gain access to private fields. This means that it will 460 * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is 461 * also not as efficient as testing explicitly. 462 * </p> 463 * 464 * <p> 465 * Transient members will be not be used, as they are likely derived fields, and not part of the value of the 466 * <code>Object</code>. 467 * </p> 468 * 469 * <p> 470 * Static fields will not be tested. Superclass fields will be included. If no fields are found to include 471 * in the hash code, the result of this method will be constant. 472 * </p> 473 * 474 * @param object 475 * the Object to create a <code>hashCode</code> for 476 * @param excludeFields 477 * array of field names to exclude from use in calculation of hash code 478 * @return int hash code 479 * @throws IllegalArgumentException 480 * if the object is <code>null</code> 481 * 482 * @see HashCodeExclude 483 */ 484 public static int reflectionHashCode(final Object object, final String... excludeFields) { 485 return reflectionHashCode(DEFAULT_INITIAL_VALUE, DEFAULT_MULTIPLIER_VALUE, object, false, 486 null, excludeFields); 487 } 488 489 /** 490 * <p> 491 * Registers the given object. Used by the reflection methods to avoid infinite loops. 492 * </p> 493 * 494 * @param value 495 * The object to register. 496 */ 497 private static void register(final Object value) { 498 Set<IDKey> registry = getRegistry(); 499 if (registry == null) { 500 registry = new HashSet<>(); 501 REGISTRY.set(registry); 502 } 503 registry.add(new IDKey(value)); 504 } 505 506 /** 507 * <p> 508 * Unregisters the given object. 509 * </p> 510 * 511 * <p> 512 * Used by the reflection methods to avoid infinite loops. 513 * 514 * @param value 515 * The object to unregister. 516 * @since 2.3 517 */ 518 private static void unregister(final Object value) { 519 final Set<IDKey> registry = getRegistry(); 520 if (registry != null) { 521 registry.remove(new IDKey(value)); 522 if (registry.isEmpty()) { 523 REGISTRY.remove(); 524 } 525 } 526 } 527 528 /** 529 * Constant to use in building the hashCode. 530 */ 531 private final int iConstant; 532 533 /** 534 * Running total of the hashCode. 535 */ 536 private int iTotal = 0; 537 538 /** 539 * <p> 540 * Uses two hard coded choices for the constants needed to build a <code>hashCode</code>. 541 * </p> 542 */ 543 public HashCodeBuilder() { 544 iConstant = 37; 545 iTotal = 17; 546 } 547 548 /** 549 * <p> 550 * Two randomly chosen, odd numbers must be passed in. Ideally these should be different for each class, 551 * however this is not vital. 552 * </p> 553 * 554 * <p> 555 * Prime numbers are preferred, especially for the multiplier. 556 * </p> 557 * 558 * @param initialOddNumber 559 * an odd number used as the initial value 560 * @param multiplierOddNumber 561 * an odd number used as the multiplier 562 * @throws IllegalArgumentException 563 * if the number is even 564 */ 565 public HashCodeBuilder(final int initialOddNumber, final int multiplierOddNumber) { 566 Validate.isTrue(initialOddNumber % 2 != 0, "HashCodeBuilder requires an odd initial value"); 567 Validate.isTrue(multiplierOddNumber % 2 != 0, "HashCodeBuilder requires an odd multiplier"); 568 iConstant = multiplierOddNumber; 569 iTotal = initialOddNumber; 570 } 571 572 /** 573 * <p> 574 * Append a <code>hashCode</code> for a <code>boolean</code>. 575 * </p> 576 * <p> 577 * This adds <code>1</code> when true, and <code>0</code> when false to the <code>hashCode</code>. 578 * </p> 579 * <p> 580 * This is in contrast to the standard <code>java.lang.Boolean.hashCode</code> handling, which computes 581 * a <code>hashCode</code> value of <code>1231</code> for <code>java.lang.Boolean</code> instances 582 * that represent <code>true</code> or <code>1237</code> for <code>java.lang.Boolean</code> instances 583 * that represent <code>false</code>. 584 * </p> 585 * <p> 586 * This is in accordance with the <i>Effective Java</i> design. 587 * </p> 588 * 589 * @param value 590 * the boolean to add to the <code>hashCode</code> 591 * @return this 592 */ 593 public HashCodeBuilder append(final boolean value) { 594 iTotal = iTotal * iConstant + (value ? 0 : 1); 595 return this; 596 } 597 598 /** 599 * <p> 600 * Append a <code>hashCode</code> for a <code>boolean</code> array. 601 * </p> 602 * 603 * @param array 604 * the array to add to the <code>hashCode</code> 605 * @return this 606 */ 607 public HashCodeBuilder append(final boolean[] array) { 608 if (array == null) { 609 iTotal = iTotal * iConstant; 610 } else { 611 for (final boolean element : array) { 612 append(element); 613 } 614 } 615 return this; 616 } 617 618 // ------------------------------------------------------------------------- 619 620 /** 621 * <p> 622 * Append a <code>hashCode</code> for a <code>byte</code>. 623 * </p> 624 * 625 * @param value 626 * the byte to add to the <code>hashCode</code> 627 * @return this 628 */ 629 public HashCodeBuilder append(final byte value) { 630 iTotal = iTotal * iConstant + value; 631 return this; 632 } 633 634 // ------------------------------------------------------------------------- 635 636 /** 637 * <p> 638 * Append a <code>hashCode</code> for a <code>byte</code> array. 639 * </p> 640 * 641 * @param array 642 * the array to add to the <code>hashCode</code> 643 * @return this 644 */ 645 public HashCodeBuilder append(final byte[] array) { 646 if (array == null) { 647 iTotal = iTotal * iConstant; 648 } else { 649 for (final byte element : array) { 650 append(element); 651 } 652 } 653 return this; 654 } 655 656 /** 657 * <p> 658 * Append a <code>hashCode</code> for a <code>char</code>. 659 * </p> 660 * 661 * @param value 662 * the char to add to the <code>hashCode</code> 663 * @return this 664 */ 665 public HashCodeBuilder append(final char value) { 666 iTotal = iTotal * iConstant + value; 667 return this; 668 } 669 670 /** 671 * <p> 672 * Append a <code>hashCode</code> for a <code>char</code> array. 673 * </p> 674 * 675 * @param array 676 * the array to add to the <code>hashCode</code> 677 * @return this 678 */ 679 public HashCodeBuilder append(final char[] array) { 680 if (array == null) { 681 iTotal = iTotal * iConstant; 682 } else { 683 for (final char element : array) { 684 append(element); 685 } 686 } 687 return this; 688 } 689 690 /** 691 * <p> 692 * Append a <code>hashCode</code> for a <code>double</code>. 693 * </p> 694 * 695 * @param value 696 * the double to add to the <code>hashCode</code> 697 * @return this 698 */ 699 public HashCodeBuilder append(final double value) { 700 return append(Double.doubleToLongBits(value)); 701 } 702 703 /** 704 * <p> 705 * Append a <code>hashCode</code> for a <code>double</code> array. 706 * </p> 707 * 708 * @param array 709 * the array to add to the <code>hashCode</code> 710 * @return this 711 */ 712 public HashCodeBuilder append(final double[] array) { 713 if (array == null) { 714 iTotal = iTotal * iConstant; 715 } else { 716 for (final double element : array) { 717 append(element); 718 } 719 } 720 return this; 721 } 722 723 /** 724 * <p> 725 * Append a <code>hashCode</code> for a <code>float</code>. 726 * </p> 727 * 728 * @param value 729 * the float to add to the <code>hashCode</code> 730 * @return this 731 */ 732 public HashCodeBuilder append(final float value) { 733 iTotal = iTotal * iConstant + Float.floatToIntBits(value); 734 return this; 735 } 736 737 /** 738 * <p> 739 * Append a <code>hashCode</code> for a <code>float</code> array. 740 * </p> 741 * 742 * @param array 743 * the array to add to the <code>hashCode</code> 744 * @return this 745 */ 746 public HashCodeBuilder append(final float[] array) { 747 if (array == null) { 748 iTotal = iTotal * iConstant; 749 } else { 750 for (final float element : array) { 751 append(element); 752 } 753 } 754 return this; 755 } 756 757 /** 758 * <p> 759 * Append a <code>hashCode</code> for an <code>int</code>. 760 * </p> 761 * 762 * @param value 763 * the int to add to the <code>hashCode</code> 764 * @return this 765 */ 766 public HashCodeBuilder append(final int value) { 767 iTotal = iTotal * iConstant + value; 768 return this; 769 } 770 771 /** 772 * <p> 773 * Append a <code>hashCode</code> for an <code>int</code> array. 774 * </p> 775 * 776 * @param array 777 * the array to add to the <code>hashCode</code> 778 * @return this 779 */ 780 public HashCodeBuilder append(final int[] array) { 781 if (array == null) { 782 iTotal = iTotal * iConstant; 783 } else { 784 for (final int element : array) { 785 append(element); 786 } 787 } 788 return this; 789 } 790 791 /** 792 * <p> 793 * Append a <code>hashCode</code> for a <code>long</code>. 794 * </p> 795 * 796 * @param value 797 * the long to add to the <code>hashCode</code> 798 * @return this 799 */ 800 // NOTE: This method uses >> and not >>> as Effective Java and 801 // Long.hashCode do. Ideally we should switch to >>> at 802 // some stage. There are backwards compat issues, so 803 // that will have to wait for the time being. cf LANG-342. 804 public HashCodeBuilder append(final long value) { 805 iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32))); 806 return this; 807 } 808 809 /** 810 * <p> 811 * Append a <code>hashCode</code> for a <code>long</code> array. 812 * </p> 813 * 814 * @param array 815 * the array to add to the <code>hashCode</code> 816 * @return this 817 */ 818 public HashCodeBuilder append(final long[] array) { 819 if (array == null) { 820 iTotal = iTotal * iConstant; 821 } else { 822 for (final long element : array) { 823 append(element); 824 } 825 } 826 return this; 827 } 828 829 /** 830 * <p> 831 * Append a <code>hashCode</code> for an <code>Object</code>. 832 * </p> 833 * 834 * @param object 835 * the Object to add to the <code>hashCode</code> 836 * @return this 837 */ 838 public HashCodeBuilder append(final Object object) { 839 if (object == null) { 840 iTotal = iTotal * iConstant; 841 842 } else { 843 if (object.getClass().isArray()) { 844 // factor out array case in order to keep method small enough 845 // to be inlined 846 appendArray(object); 847 } else { 848 iTotal = iTotal * iConstant + object.hashCode(); 849 } 850 } 851 return this; 852 } 853 854 /** 855 * <p> 856 * Append a <code>hashCode</code> for an array. 857 * </p> 858 * 859 * @param object 860 * the array to add to the <code>hashCode</code> 861 */ 862 private void appendArray(final Object object) { 863 // 'Switch' on type of array, to dispatch to the correct handler 864 // This handles multi dimensional arrays 865 if (object instanceof long[]) { 866 append((long[]) object); 867 } else if (object instanceof int[]) { 868 append((int[]) object); 869 } else if (object instanceof short[]) { 870 append((short[]) object); 871 } else if (object instanceof char[]) { 872 append((char[]) object); 873 } else if (object instanceof byte[]) { 874 append((byte[]) object); 875 } else if (object instanceof double[]) { 876 append((double[]) object); 877 } else if (object instanceof float[]) { 878 append((float[]) object); 879 } else if (object instanceof boolean[]) { 880 append((boolean[]) object); 881 } else { 882 // Not an array of primitives 883 append((Object[]) object); 884 } 885 } 886 887 /** 888 * <p> 889 * Append a <code>hashCode</code> for an <code>Object</code> array. 890 * </p> 891 * 892 * @param array 893 * the array to add to the <code>hashCode</code> 894 * @return this 895 */ 896 public HashCodeBuilder append(final Object[] array) { 897 if (array == null) { 898 iTotal = iTotal * iConstant; 899 } else { 900 for (final Object element : array) { 901 append(element); 902 } 903 } 904 return this; 905 } 906 907 /** 908 * <p> 909 * Append a <code>hashCode</code> for a <code>short</code>. 910 * </p> 911 * 912 * @param value 913 * the short to add to the <code>hashCode</code> 914 * @return this 915 */ 916 public HashCodeBuilder append(final short value) { 917 iTotal = iTotal * iConstant + value; 918 return this; 919 } 920 921 /** 922 * <p> 923 * Append a <code>hashCode</code> for a <code>short</code> array. 924 * </p> 925 * 926 * @param array 927 * the array to add to the <code>hashCode</code> 928 * @return this 929 */ 930 public HashCodeBuilder append(final short[] array) { 931 if (array == null) { 932 iTotal = iTotal * iConstant; 933 } else { 934 for (final short element : array) { 935 append(element); 936 } 937 } 938 return this; 939 } 940 941 /** 942 * <p> 943 * Adds the result of super.hashCode() to this builder. 944 * </p> 945 * 946 * @param superHashCode 947 * the result of calling <code>super.hashCode()</code> 948 * @return this HashCodeBuilder, used to chain calls. 949 * @since 2.0 950 */ 951 public HashCodeBuilder appendSuper(final int superHashCode) { 952 iTotal = iTotal * iConstant + superHashCode; 953 return this; 954 } 955 956 /** 957 * <p> 958 * Return the computed <code>hashCode</code>. 959 * </p> 960 * 961 * @return <code>hashCode</code> based on the fields appended 962 */ 963 public int toHashCode() { 964 return iTotal; 965 } 966 967 /** 968 * Returns the computed <code>hashCode</code>. 969 * 970 * @return <code>hashCode</code> based on the fields appended 971 * 972 * @since 3.0 973 */ 974 @Override 975 public Integer build() { 976 return Integer.valueOf(toHashCode()); 977 } 978 979 /** 980 * <p> 981 * The computed <code>hashCode</code> from toHashCode() is returned due to the likelihood 982 * of bugs in mis-calling toHashCode() and the unlikeliness of it mattering what the hashCode for 983 * HashCodeBuilder itself is.</p> 984 * 985 * @return <code>hashCode</code> based on the fields appended 986 * @since 2.5 987 */ 988 @Override 989 public int hashCode() { 990 return toHashCode(); 991 } 992 993}