| 1 16 17 package org.cojen.util; 18 19 import java.util.Arrays ; 20 21 29 public class KeyFactory { 30 static final Object NULL = new Comparable () { 31 public int compareTo(Object obj) { 32 return obj == this || obj == null ? 0 : 1; 33 } 34 }; 35 36 public static Object createKey(boolean[] obj) { 37 return obj == null ? NULL : new BooleanArrayKey(obj); 38 } 39 40 public static Object createKey(byte[] obj) { 41 return obj == null ? NULL : new ByteArrayKey(obj); 42 } 43 44 public static Object createKey(char[] obj) { 45 return obj == null ? NULL : new CharArrayKey(obj); 46 } 47 48 public static Object createKey(double[] obj) { 49 return obj == null ? NULL : new DoubleArrayKey(obj); 50 } 51 52 public static Object createKey(float[] obj) { 53 return obj == null ? NULL : new FloatArrayKey(obj); 54 } 55 56 public static Object createKey(int[] obj) { 57 return obj == null ? NULL : new IntArrayKey(obj); 58 } 59 60 public static Object createKey(long[] obj) { 61 return obj == null ? NULL : new LongArrayKey(obj); 62 } 63 64 public static Object createKey(short[] obj) { 65 return obj == null ? NULL : new ShortArrayKey(obj); 66 } 67 68 public static Object createKey(Object [] obj) { 69 return obj == null ? NULL : new ObjectArrayKey(obj); 70 } 71 72 public static Object createKey(Object obj) { 73 if (obj == null) { 74 return NULL; 75 } 76 if (!obj.getClass().isArray()) { 77 return obj; 78 } 79 if (obj instanceof Object []) { 80 return createKey((Object [])obj); 81 } else if (obj instanceof int[]) { 82 return createKey((int[])obj); 83 } else if (obj instanceof float[]) { 84 return createKey((float[])obj); 85 } else if (obj instanceof long[]) { 86 return createKey((long[])obj); 87 } else if (obj instanceof double[]) { 88 return createKey((double[])obj); 89 } else if (obj instanceof byte[]) { 90 return createKey((byte[])obj); 91 } else if (obj instanceof char[]) { 92 return createKey((char[])obj); 93 } else if (obj instanceof boolean[]) { 94 return createKey((boolean[])obj); 95 } else if (obj instanceof short[]) { 96 return createKey((short[])obj); 97 } else { 98 return obj; 99 } 100 } 101 102 static int hashCode(boolean[] a) { 103 int hash = 0; 104 for (int i = a.length; --i >= 0; ) { 105 hash = (hash << 1) + (a[i] ? 0 : 1); 106 } 107 return hash == 0 ? -1 : hash; 108 } 109 110 static int hashCode(byte[] a) { 111 int hash = 0; 112 for (int i = a.length; --i >= 0; ) { 113 hash = (hash << 1) + a[i]; 114 } 115 return hash == 0 ? -1 : hash; 116 } 117 118 static int hashCode(char[] a) { 119 int hash = 0; 120 for (int i = a.length; --i >= 0; ) { 121 hash = (hash << 1) + a[i]; 122 } 123 return hash == 0 ? -1 : hash; 124 } 125 126 static int hashCode(double[] a) { 127 int hash = 0; 128 for (int i = a.length; --i >= 0; ) { 129 long v = Double.doubleToLongBits(a[i]); 130 hash = hash * 31 + (int)(v ^ v >>> 32); 131 } 132 return hash == 0 ? -1 : hash; 133 } 134 135 static int hashCode(float[] a) { 136 int hash = 0; 137 for (int i = a.length; --i >= 0; ) { 138 hash = hash * 31 + Float.floatToIntBits(a[i]); 139 } 140 return hash == 0 ? -1 : hash; 141 } 142 143 static int hashCode(int[] a) { 144 int hash = 0; 145 for (int i = a.length; --i >= 0; ) { 146 hash = (hash << 1) + a[i]; 147 } 148 return hash == 0 ? -1 : hash; 149 } 150 151 static int hashCode(long[] a) { 152 int hash = 0; 153 for (int i = a.length; --i >= 0; ) { 154 long v = a[i]; 155 hash = hash * 31 + (int)(v ^ v >>> 32); 156 } 157 return hash == 0 ? -1 : hash; 158 } 159 160 static int hashCode(short[] a) { 161 int hash = 0; 162 for (int i = a.length; --i >= 0; ) { 163 hash = (hash << 1) + a[i]; 164 } 165 return hash == 0 ? -1 : hash; 166 } 167 168 static int hashCode(Object [] a) { 169 int hash = 0; 170 for (int i = a.length; --i >= 0; ) { 171 hash = hash * 31 + hashCode(a[i]); 172 } 173 return hash == 0 ? -1 : hash; 174 } 175 176 static int hashCode(Object a) { 178 if (a == null) { 179 return -1; 180 } 181 if (!a.getClass().isArray()) { 182 return a.hashCode(); 183 } 184 if (a instanceof Object []) { 185 return hashCode((Object [])a); 186 } else if (a instanceof int[]) { 187 return hashCode((int[])a); 188 } else if (a instanceof float[]) { 189 return hashCode((float[])a); 190 } else if (a instanceof long[]) { 191 return hashCode((long[])a); 192 } else if (a instanceof double[]) { 193 return hashCode((double[])a); 194 } else if (a instanceof byte[]) { 195 return hashCode((byte[])a); 196 } else if (a instanceof char[]) { 197 return hashCode((char[])a); 198 } else if (a instanceof boolean[]) { 199 return hashCode((boolean[])a); 200 } else if (a instanceof short[]) { 201 return hashCode((short[])a); 202 } else { 203 int hash = a.getClass().hashCode(); 204 return hash == 0 ? -1 : hash; 205 } 206 } 207 208 static boolean equals(Object [] a, Object [] b) { 210 if (a == b) { 211 return true; 212 } 213 if (a == null || b == null) { 214 return false; 215 } 216 int i; 217 if ((i = a.length) != b.length) { 218 return false; 219 } 220 while (--i >= 0) { 221 if (!equals(a[i], b[i])) { 222 return false; 223 } 224 } 225 return true; 226 } 227 228 static boolean equals(Object a, Object b) { 230 if (a == b) { 231 return true; 232 } 233 if (a == null || b == null) { 234 return false; 235 } 236 Class ac = a.getClass(); 237 if (!(ac.isArray())) { 238 return a.equals(b); 239 } 240 if (ac != b.getClass()) { 241 return false; 242 } 243 if (a instanceof Object []) { 244 return equals((Object [])a, (Object [])b); 245 } else if (a instanceof int[]) { 246 return Arrays.equals((int[])a, (int[])b); 247 } else if (a instanceof float[]) { 248 return Arrays.equals((float[])a, (float[])b); 249 } else if (a instanceof long[]) { 250 return Arrays.equals((long[])a, (long[])b); 251 } else if (a instanceof double[]) { 252 return Arrays.equals((double[])a, (double[])b); 253 } else if (a instanceof byte[]) { 254 return Arrays.equals((byte[])a, (byte[])b); 255 } else if (a instanceof char[]) { 256 return Arrays.equals((char[])a, (char[])b); 257 } else if (a instanceof boolean[]) { 258 return Arrays.equals((boolean[])a, (boolean[])b); 259 } else if (a instanceof short[]) { 260 return Arrays.equals((short[])a, (short[])b); 261 } else { 262 return a.equals(b); 263 } 264 } 265 266 static int compare(boolean[] a, boolean[] b) { 267 if (a == b) { 268 return 0; 269 } 270 if (a == null) { 271 return 1; 272 } 273 if (b == null) { 274 return -1; 275 } 276 int length = Math.min(a.length, b.length); 277 for (int i=0; i<length; i++) { 278 int av = a[i] ? 0 : 1; 279 int bv = b[i] ? 0 : 1; 280 return av < bv ? -1 : (av > bv ? 1 : 0); 281 } 282 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 283 } 284 285 static int compare(byte[] a, byte[] b) { 286 if (a == b) { 287 return 0; 288 } 289 if (a == null) { 290 return 1; 291 } 292 if (b == null) { 293 return -1; 294 } 295 int length = Math.min(a.length, b.length); 296 for (int i=0; i<length; i++) { 297 byte av = a[i]; 298 byte bv = b[i]; 299 return av < bv ? -1 : (av > bv ? 1 : 0); 300 } 301 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 302 } 303 304 static int compare(char[] a, char[] b) { 305 if (a == b) { 306 return 0; 307 } 308 if (a == null) { 309 return 1; 310 } 311 if (b == null) { 312 return -1; 313 } 314 int length = Math.min(a.length, b.length); 315 for (int i=0; i<length; i++) { 316 char av = a[i]; 317 char bv = b[i]; 318 return av < bv ? -1 : (av > bv ? 1 : 0); 319 } 320 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 321 } 322 323 static int compare(double[] a, double[] b) { 324 if (a == b) { 325 return 0; 326 } 327 if (a == null) { 328 return 1; 329 } 330 if (b == null) { 331 return -1; 332 } 333 int length = Math.min(a.length, b.length); 334 for (int i=0; i<length; i++) { 335 int v = Double.compare(a[i], b[i]); 336 if (v != 0) { 337 return v; 338 } 339 } 340 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 341 } 342 343 static int compare(float[] a, float[] b) { 344 if (a == b) { 345 return 0; 346 } 347 if (a == null) { 348 return 1; 349 } 350 if (b == null) { 351 return -1; 352 } 353 int length = Math.min(a.length, b.length); 354 for (int i=0; i<length; i++) { 355 int v = Float.compare(a[i], b[i]); 356 if (v != 0) { 357 return v; 358 } 359 } 360 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 361 } 362 363 static int compare(int[] a, int[] b) { 364 if (a == b) { 365 return 0; 366 } 367 if (a == null) { 368 return 1; 369 } 370 if (b == null) { 371 return -1; 372 } 373 int length = Math.min(a.length, b.length); 374 for (int i=0; i<length; i++) { 375 int av = a[i]; 376 int bv = b[i]; 377 return av < bv ? -1 : (av > bv ? 1 : 0); 378 } 379 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 380 } 381 382 static int compare(long[] a, long[] b) { 383 if (a == b) { 384 return 0; 385 } 386 if (a == null) { 387 return 1; 388 } 389 if (b == null) { 390 return -1; 391 } 392 int length = Math.min(a.length, b.length); 393 for (int i=0; i<length; i++) { 394 long av = a[i]; 395 long bv = b[i]; 396 return av < bv ? -1 : (av > bv ? 1 : 0); 397 } 398 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 399 } 400 401 static int compare(short[] a, short[] b) { 402 if (a == b) { 403 return 0; 404 } 405 if (a == null) { 406 return 1; 407 } 408 if (b == null) { 409 return -1; 410 } 411 int length = Math.min(a.length, b.length); 412 for (int i=0; i<length; i++) { 413 short av = a[i]; 414 short bv = b[i]; 415 return av < bv ? -1 : (av > bv ? 1 : 0); 416 } 417 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 418 } 419 420 static int compare(Object [] a, Object [] b) { 422 if (a == b) { 423 return 0; 424 } 425 if (a == null) { 426 return 1; 427 } 428 if (b == null) { 429 return -1; 430 } 431 int length = Math.min(a.length, b.length); 432 for (int i=0; i<length; i++) { 433 int v = compare(a[i], b[i]); 434 if (v != 0) { 435 return v; 436 } 437 } 438 return a.length < b.length ? -1 : (a.length > b.length ? 1 : 0); 439 } 440 441 static int compare(Object a, Object b) { 443 if (a == b) { 444 return 0; 445 } 446 if (a == null) { 447 return 1; 448 } 449 if (b == null) { 450 return -1; 451 } 452 Class ac = a.getClass(); 453 if (!(ac.isArray())) { 454 return ((Comparable )a).compareTo(b); 455 } 456 if (ac != b.getClass()) { 457 throw new ClassCastException (); 458 } 459 if (a instanceof Object []) { 460 return compare((Object [])a, (Object [])b); 461 } else if (a instanceof int[]) { 462 return compare((int[])a, (int[])b); 463 } else if (a instanceof float[]) { 464 return compare((float[])a, (float[])b); 465 } else if (a instanceof long[]) { 466 return compare((long[])a, (long[])b); 467 } else if (a instanceof double[]) { 468 return compare((double[])a, (double[])b); 469 } else if (a instanceof byte[]) { 470 return compare((byte[])a, (byte[])b); 471 } else if (a instanceof char[]) { 472 return compare((char[])a, (char[])b); 473 } else if (a instanceof boolean[]) { 474 return compare((boolean[])a, (boolean[])b); 475 } else if (a instanceof short[]) { 476 return compare((short[])a, (short[])b); 477 } else { 478 throw new ClassCastException (); 479 } 480 } 481 482 protected KeyFactory() { 483 } 484 485 private static interface ArrayKey extends Comparable , java.io.Serializable { 486 int hashCode(); 487 488 boolean equals(Object obj); 489 490 int compareTo(Object obj); 491 } 492 493 private static class BooleanArrayKey implements ArrayKey { 494 protected final boolean[] mArray; 495 private transient int mHash; 496 497 BooleanArrayKey(boolean[] array) { 498 mArray = array; 499 } 500 501 public int hashCode() { 502 int hash = mHash; 503 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 504 } 505 506 public boolean equals(Object obj) { 507 return this == obj ? true : 508 (obj instanceof BooleanArrayKey ? 509 Arrays.equals(mArray, ((BooleanArrayKey) obj).mArray) : false); 510 } 511 512 public int compareTo(Object obj) { 513 return compare(mArray, ((BooleanArrayKey) obj).mArray); 514 } 515 } 516 517 private static class ByteArrayKey implements ArrayKey { 518 protected final byte[] mArray; 519 private transient int mHash; 520 521 ByteArrayKey(byte[] array) { 522 mArray = array; 523 } 524 525 public int hashCode() { 526 int hash = mHash; 527 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 528 } 529 530 public boolean equals(Object obj) { 531 return this == obj ? true : 532 (obj instanceof ByteArrayKey ? 533 Arrays.equals(mArray, ((ByteArrayKey) obj).mArray) : false); 534 } 535 536 public int compareTo(Object obj) { 537 return compare(mArray, ((ByteArrayKey) obj).mArray); 538 } 539 } 540 541 private static class CharArrayKey implements ArrayKey { 542 protected final char[] mArray; 543 private transient int mHash; 544 545 CharArrayKey(char[] array) { 546 mArray = array; 547 } 548 549 public int hashCode() { 550 int hash = mHash; 551 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 552 } 553 554 public boolean equals(Object obj) { 555 return this == obj ? true : 556 (obj instanceof CharArrayKey ? 557 Arrays.equals(mArray, ((CharArrayKey) obj).mArray) : false); 558 } 559 560 public int compareTo(Object obj) { 561 return compare(mArray, ((CharArrayKey) obj).mArray); 562 } 563 } 564 565 private static class DoubleArrayKey implements ArrayKey { 566 protected final double[] mArray; 567 private transient int mHash; 568 569 DoubleArrayKey(double[] array) { 570 mArray = array; 571 } 572 573 public int hashCode() { 574 int hash = mHash; 575 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 576 } 577 578 public boolean equals(Object obj) { 579 return this == obj ? true : 580 (obj instanceof DoubleArrayKey ? 581 Arrays.equals(mArray, ((DoubleArrayKey) obj).mArray) : false); 582 } 583 584 public int compareTo(Object obj) { 585 return compare(mArray, ((DoubleArrayKey) obj).mArray); 586 } 587 } 588 589 private static class FloatArrayKey implements ArrayKey { 590 protected final float[] mArray; 591 private transient int mHash; 592 593 FloatArrayKey(float[] array) { 594 mArray = array; 595 } 596 597 public int hashCode() { 598 int hash = mHash; 599 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 600 } 601 602 public boolean equals(Object obj) { 603 return this == obj ? true : 604 (obj instanceof FloatArrayKey ? 605 Arrays.equals(mArray, ((FloatArrayKey) obj).mArray) : false); 606 } 607 608 public int compareTo(Object obj) { 609 return compare(mArray, ((FloatArrayKey) obj).mArray); 610 } 611 } 612 613 private static class IntArrayKey implements ArrayKey { 614 protected final int[] mArray; 615 private transient int mHash; 616 617 IntArrayKey(int[] array) { 618 mArray = array; 619 } 620 621 public int hashCode() { 622 int hash = mHash; 623 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 624 } 625 626 public boolean equals(Object obj) { 627 return this == obj ? true : 628 (obj instanceof IntArrayKey ? 629 Arrays.equals(mArray, ((IntArrayKey) obj).mArray) : false); 630 } 631 632 public int compareTo(Object obj) { 633 return compare(mArray, ((IntArrayKey) obj).mArray); 634 } 635 } 636 637 private static class LongArrayKey implements ArrayKey { 638 protected final long[] mArray; 639 private transient int mHash; 640 641 LongArrayKey(long[] array) { 642 mArray = array; 643 } 644 645 public int hashCode() { 646 int hash = mHash; 647 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 648 } 649 650 public boolean equals(Object obj) { 651 return this == obj ? true : 652 (obj instanceof LongArrayKey ? 653 Arrays.equals(mArray, ((LongArrayKey) obj).mArray) : false); 654 } 655 656 public int compareTo(Object obj) { 657 return compare(mArray, ((LongArrayKey) obj).mArray); 658 } 659 } 660 661 private static class ShortArrayKey implements ArrayKey { 662 protected final short[] mArray; 663 private transient int mHash; 664 665 ShortArrayKey(short[] array) { 666 mArray = array; 667 } 668 669 public int hashCode() { 670 int hash = mHash; 671 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 672 } 673 674 public boolean equals(Object obj) { 675 return this == obj ? true : 676 (obj instanceof ShortArrayKey ? 677 Arrays.equals(mArray, ((ShortArrayKey) obj).mArray) : false); 678 } 679 680 public int compareTo(Object obj) { 681 return compare(mArray, ((ShortArrayKey) obj).mArray); 682 } 683 } 684 685 private static class ObjectArrayKey implements ArrayKey { 686 protected final Object [] mArray; 687 private transient int mHash; 688 689 ObjectArrayKey(Object [] array) { 690 mArray = array; 691 } 692 693 public int hashCode() { 694 int hash = mHash; 695 return hash == 0 ? mHash = KeyFactory.hashCode(mArray) : hash; 696 } 697 698 public boolean equals(Object obj) { 699 return this == obj ? true : 700 (obj instanceof ObjectArrayKey ? 701 KeyFactory.equals(mArray, ((ObjectArrayKey) obj).mArray) : false); 702 } 703 704 public int compareTo(Object obj) { 705 return compare(mArray, ((ObjectArrayKey) obj).mArray); 706 } 707 } 708 } 709 | Popular Tags |