1 16 package org.apache.commons.lang.builder; 17 18 import java.lang.reflect.AccessibleObject ; 19 import java.lang.reflect.Field ; 20 import java.lang.reflect.Modifier ; 21 22 79 public class HashCodeBuilder { 80 81 84 private final int iConstant; 85 88 private int iTotal = 0; 89 90 94 public HashCodeBuilder() { 95 iConstant = 37; 96 iTotal = 17; 97 } 98 99 110 public HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) { 111 if (initialNonZeroOddNumber == 0) { 112 throw new IllegalArgumentException ("HashCodeBuilder requires a non zero initial value"); 113 } 114 if (initialNonZeroOddNumber % 2 == 0) { 115 throw new IllegalArgumentException ("HashCodeBuilder requires an odd initial value"); 116 } 117 if (multiplierNonZeroOddNumber == 0) { 118 throw new IllegalArgumentException ("HashCodeBuilder requires a non zero multiplier"); 119 } 120 if (multiplierNonZeroOddNumber % 2 == 0) { 121 throw new IllegalArgumentException ("HashCodeBuilder requires an odd multiplier"); 122 } 123 iConstant = multiplierNonZeroOddNumber; 124 iTotal = initialNonZeroOddNumber; 125 } 126 127 129 149 public static int reflectionHashCode(Object object) { 150 return reflectionHashCode(17, 37, object, false, null); 151 } 152 153 175 public static int reflectionHashCode(Object object, boolean testTransients) { 176 return reflectionHashCode(17, 37, object, testTransients, null); 177 } 178 179 203 public static int reflectionHashCode( 204 int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, Object object) { 205 return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, false, null); 206 } 207 208 234 public static int reflectionHashCode( 235 int initialNonZeroOddNumber, int multiplierNonZeroOddNumber, 236 Object object, boolean testTransients) { 237 return reflectionHashCode(initialNonZeroOddNumber, multiplierNonZeroOddNumber, object, testTransients, null); 238 } 239 240 271 public static int reflectionHashCode( 272 int initialNonZeroOddNumber, 273 int multiplierNonZeroOddNumber, 274 Object object, 275 boolean testTransients, 276 Class reflectUpToClass) { 277 278 if (object == null) { 279 throw new IllegalArgumentException ("The object to build a hash code for must not be null"); 280 } 281 HashCodeBuilder builder = new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber); 282 Class clazz = object.getClass(); 283 reflectionAppend(object, clazz, builder, testTransients); 284 while (clazz.getSuperclass() != null && clazz != reflectUpToClass) { 285 clazz = clazz.getSuperclass(); 286 reflectionAppend(object, clazz, builder, testTransients); 287 } 288 return builder.toHashCode(); 289 } 290 291 300 private static void reflectionAppend(Object object, Class clazz, HashCodeBuilder builder, boolean useTransients) { 301 Field [] fields = clazz.getDeclaredFields(); 302 AccessibleObject.setAccessible(fields, true); 303 for (int i = 0; i < fields.length; i++) { 304 Field f = fields[i]; 305 if ((f.getName().indexOf('$') == -1) 306 && (useTransients || !Modifier.isTransient(f.getModifiers())) 307 && (!Modifier.isStatic(f.getModifiers()))) { 308 try { 309 builder.append(f.get(object)); 310 } catch (IllegalAccessException e) { 311 throw new InternalError ("Unexpected IllegalAccessException"); 314 } 315 } 316 } 317 } 318 319 321 328 public HashCodeBuilder appendSuper(int superHashCode) { 329 iTotal = iTotal * iConstant + superHashCode; 330 return this; 331 } 332 333 335 341 public HashCodeBuilder append(Object object) { 342 if (object == null) { 343 iTotal = iTotal * iConstant; 344 345 } else { 346 if (object.getClass().isArray() == false) { 347 iTotal = iTotal * iConstant + object.hashCode(); 349 350 } else { 351 if (object instanceof long[]) { 354 append((long[]) object); 355 } else if (object instanceof int[]) { 356 append((int[]) object); 357 } else if (object instanceof short[]) { 358 append((short[]) object); 359 } else if (object instanceof char[]) { 360 append((char[]) object); 361 } else if (object instanceof byte[]) { 362 append((byte[]) object); 363 } else if (object instanceof double[]) { 364 append((double[]) object); 365 } else if (object instanceof float[]) { 366 append((float[]) object); 367 } else if (object instanceof boolean[]) { 368 append((boolean[]) object); 369 } else { 370 append((Object []) object); 372 } 373 } 374 } 375 return this; 376 } 377 378 384 public HashCodeBuilder append(long value) { 385 iTotal = iTotal * iConstant + ((int) (value ^ (value >> 32))); 386 return this; 387 } 388 389 395 public HashCodeBuilder append(int value) { 396 iTotal = iTotal * iConstant + value; 397 return this; 398 } 399 400 406 public HashCodeBuilder append(short value) { 407 iTotal = iTotal * iConstant + value; 408 return this; 409 } 410 411 417 public HashCodeBuilder append(char value) { 418 iTotal = iTotal * iConstant + value; 419 return this; 420 } 421 422 428 public HashCodeBuilder append(byte value) { 429 iTotal = iTotal * iConstant + value; 430 return this; 431 } 432 433 439 public HashCodeBuilder append(double value) { 440 return append(Double.doubleToLongBits(value)); 441 } 442 443 449 public HashCodeBuilder append(float value) { 450 iTotal = iTotal * iConstant + Float.floatToIntBits(value); 451 return this; 452 } 453 454 463 public HashCodeBuilder append(boolean value) { 464 iTotal = iTotal * iConstant + (value ? 0 : 1); 465 return this; 466 } 467 468 474 public HashCodeBuilder append(Object [] array) { 475 if (array == null) { 476 iTotal = iTotal * iConstant; 477 } else { 478 for (int i = 0; i < array.length; i++) { 479 append(array[i]); 480 } 481 } 482 return this; 483 } 484 485 491 public HashCodeBuilder append(long[] array) { 492 if (array == null) { 493 iTotal = iTotal * iConstant; 494 } else { 495 for (int i = 0; i < array.length; i++) { 496 append(array[i]); 497 } 498 } 499 return this; 500 } 501 502 508 public HashCodeBuilder append(int[] array) { 509 if (array == null) { 510 iTotal = iTotal * iConstant; 511 } else { 512 for (int i = 0; i < array.length; i++) { 513 append(array[i]); 514 } 515 } 516 return this; 517 } 518 519 525 public HashCodeBuilder append(short[] array) { 526 if (array == null) { 527 iTotal = iTotal * iConstant; 528 } else { 529 for (int i = 0; i < array.length; i++) { 530 append(array[i]); 531 } 532 } 533 return this; 534 } 535 536 542 public HashCodeBuilder append(char[] array) { 543 if (array == null) { 544 iTotal = iTotal * iConstant; 545 } else { 546 for (int i = 0; i < array.length; i++) { 547 append(array[i]); 548 } 549 } 550 return this; 551 } 552 553 559 public HashCodeBuilder append(byte[] array) { 560 if (array == null) { 561 iTotal = iTotal * iConstant; 562 } else { 563 for (int i = 0; i < array.length; i++) { 564 append(array[i]); 565 } 566 } 567 return this; 568 } 569 570 576 public HashCodeBuilder append(double[] array) { 577 if (array == null) { 578 iTotal = iTotal * iConstant; 579 } else { 580 for (int i = 0; i < array.length; i++) { 581 append(array[i]); 582 } 583 } 584 return this; 585 } 586 587 593 public HashCodeBuilder append(float[] array) { 594 if (array == null) { 595 iTotal = iTotal * iConstant; 596 } else { 597 for (int i = 0; i < array.length; i++) { 598 append(array[i]); 599 } 600 } 601 return this; 602 } 603 604 610 public HashCodeBuilder append(boolean[] array) { 611 if (array == null) { 612 iTotal = iTotal * iConstant; 613 } else { 614 for (int i = 0; i < array.length; i++) { 615 append(array[i]); 616 } 617 } 618 return this; 619 } 620 621 626 public int toHashCode() { 627 return iTotal; 628 } 629 630 } 631 | Popular Tags |