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