1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.util; 19 20import java.io.Serializable; 21import java.lang.reflect.Array; 22 23/** 24 * {@code Arrays} contains static methods which operate on arrays. 25 * 26 * @since 1.2 27 */ 28public class Arrays { 29 private static class ArrayList<E> extends AbstractList<E> implements 30 List<E>, Serializable, RandomAccess { 31 32 private static final long serialVersionUID = -2764017481108945198L; 33 34 private final E[] a; 35 36 ArrayList(E[] storage) { 37 if (storage == null) { 38 throw new NullPointerException("storage == null"); 39 } 40 a = storage; 41 } 42 43 @Override 44 public boolean contains(Object object) { 45 if (object != null) { 46 for (E element : a) { 47 if (object.equals(element)) { 48 return true; 49 } 50 } 51 } else { 52 for (E element : a) { 53 if (element == null) { 54 return true; 55 } 56 } 57 } 58 return false; 59 } 60 61 @Override 62 public E get(int location) { 63 try { 64 return a[location]; 65 } catch (ArrayIndexOutOfBoundsException e) { 66 throw java.util.ArrayList.throwIndexOutOfBoundsException(location, a.length); 67 } 68 } 69 70 @Override 71 public int indexOf(Object object) { 72 if (object != null) { 73 for (int i = 0; i < a.length; i++) { 74 if (object.equals(a[i])) { 75 return i; 76 } 77 } 78 } else { 79 for (int i = 0; i < a.length; i++) { 80 if (a[i] == null) { 81 return i; 82 } 83 } 84 } 85 return -1; 86 } 87 88 @Override 89 public int lastIndexOf(Object object) { 90 if (object != null) { 91 for (int i = a.length - 1; i >= 0; i--) { 92 if (object.equals(a[i])) { 93 return i; 94 } 95 } 96 } else { 97 for (int i = a.length - 1; i >= 0; i--) { 98 if (a[i] == null) { 99 return i; 100 } 101 } 102 } 103 return -1; 104 } 105 106 @Override 107 public E set(int location, E object) { 108 E result = a[location]; 109 a[location] = object; 110 return result; 111 } 112 113 @Override 114 public int size() { 115 return a.length; 116 } 117 118 @Override 119 public Object[] toArray() { 120 return a.clone(); 121 } 122 123 @Override 124 @SuppressWarnings({"unchecked", "SuspiciousSystemArraycopy"}) 125 public <T> T[] toArray(T[] contents) { 126 int size = size(); 127 if (size > contents.length) { 128 Class<?> ct = contents.getClass().getComponentType(); 129 contents = (T[]) Array.newInstance(ct, size); 130 } 131 System.arraycopy(a, 0, contents, 0, size); 132 if (size < contents.length) { 133 contents[size] = null; 134 } 135 return contents; 136 } 137 } 138 139 private Arrays() { 140 /* empty */ 141 } 142 143 /** 144 * Returns a {@code List} of the objects in the specified array. The size of the 145 * {@code List} cannot be modified, i.e. adding and removing are unsupported, but 146 * the elements can be set. Setting an element modifies the underlying 147 * array. 148 * 149 * @param array 150 * the array. 151 * @return a {@code List} of the elements of the specified array. 152 */ 153 @SafeVarargs 154 public static <T> List<T> asList(T... array) { 155 return new ArrayList<T>(array); 156 } 157 158 /** 159 * Performs a binary search for {@code value} in the ascending sorted array {@code array}. 160 * Searching in an unsorted array has an undefined result. It's also undefined which element 161 * is found if there are multiple occurrences of the same element. 162 * 163 * @param array the sorted array to search. 164 * @param value the element to find. 165 * @return the non-negative index of the element, or a negative index which 166 * is {@code -index - 1} where the element would be inserted. 167 */ 168 public static int binarySearch(byte[] array, byte value) { 169 return binarySearch(array, 0, array.length, value); 170 } 171 172 /** 173 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 174 * in the range specified by fromIndex (inclusive) and toIndex (exclusive). 175 * Searching in an unsorted array has an undefined result. It's also undefined which element 176 * is found if there are multiple occurrences of the same element. 177 * 178 * @param array the sorted array to search. 179 * @param startIndex the inclusive start index. 180 * @param endIndex the exclusive start index. 181 * @param value the element to find. 182 * @return the non-negative index of the element, or a negative index which 183 * is {@code -index - 1} where the element would be inserted. 184 * @throws IllegalArgumentException if {@code startIndex > endIndex} 185 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 186 * @since 1.6 187 */ 188 public static int binarySearch(byte[] array, int startIndex, int endIndex, byte value) { 189 checkBinarySearchBounds(startIndex, endIndex, array.length); 190 int lo = startIndex; 191 int hi = endIndex - 1; 192 193 while (lo <= hi) { 194 int mid = (lo + hi) >>> 1; 195 byte midVal = array[mid]; 196 197 if (midVal < value) { 198 lo = mid + 1; 199 } else if (midVal > value) { 200 hi = mid - 1; 201 } else { 202 return mid; // value found 203 } 204 } 205 return ~lo; // value not present 206 } 207 208 /** 209 * Performs a binary search for {@code value} in the ascending sorted array {@code array}. 210 * Searching in an unsorted array has an undefined result. It's also undefined which element 211 * is found if there are multiple occurrences of the same element. 212 * 213 * @param array the sorted array to search. 214 * @param value the element to find. 215 * @return the non-negative index of the element, or a negative index which 216 * is {@code -index - 1} where the element would be inserted. 217 */ 218 public static int binarySearch(char[] array, char value) { 219 return binarySearch(array, 0, array.length, value); 220 } 221 222 /** 223 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 224 * in the range specified by fromIndex (inclusive) and toIndex (exclusive). 225 * Searching in an unsorted array has an undefined result. It's also undefined which element 226 * is found if there are multiple occurrences of the same element. 227 * 228 * @param array the sorted array to search. 229 * @param startIndex the inclusive start index. 230 * @param endIndex the exclusive start index. 231 * @param value the element to find. 232 * @return the non-negative index of the element, or a negative index which 233 * is {@code -index - 1} where the element would be inserted. 234 * @throws IllegalArgumentException if {@code startIndex > endIndex} 235 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 236 * @since 1.6 237 */ 238 public static int binarySearch(char[] array, int startIndex, int endIndex, char value) { 239 checkBinarySearchBounds(startIndex, endIndex, array.length); 240 int lo = startIndex; 241 int hi = endIndex - 1; 242 243 while (lo <= hi) { 244 int mid = (lo + hi) >>> 1; 245 char midVal = array[mid]; 246 247 if (midVal < value) { 248 lo = mid + 1; 249 } else if (midVal > value) { 250 hi = mid - 1; 251 } else { 252 return mid; // value found 253 } 254 } 255 return ~lo; // value not present 256 } 257 258 /** 259 * Performs a binary search for {@code value} in the ascending sorted array {@code array}. 260 * Searching in an unsorted array has an undefined result. It's also undefined which element 261 * is found if there are multiple occurrences of the same element. 262 * 263 * @param array the sorted array to search. 264 * @param value the element to find. 265 * @return the non-negative index of the element, or a negative index which 266 * is {@code -index - 1} where the element would be inserted. 267 */ 268 public static int binarySearch(double[] array, double value) { 269 return binarySearch(array, 0, array.length, value); 270 } 271 272 /** 273 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 274 * in the range specified by fromIndex (inclusive) and toIndex (exclusive). 275 * Searching in an unsorted array has an undefined result. It's also undefined which element 276 * is found if there are multiple occurrences of the same element. 277 * 278 * @param array the sorted array to search. 279 * @param startIndex the inclusive start index. 280 * @param endIndex the exclusive start index. 281 * @param value the element to find. 282 * @return the non-negative index of the element, or a negative index which 283 * is {@code -index - 1} where the element would be inserted. 284 * @throws IllegalArgumentException if {@code startIndex > endIndex} 285 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 286 * @since 1.6 287 */ 288 public static int binarySearch(double[] array, int startIndex, int endIndex, double value) { 289 checkBinarySearchBounds(startIndex, endIndex, array.length); 290 int lo = startIndex; 291 int hi = endIndex - 1; 292 293 while (lo <= hi) { 294 int mid = (lo + hi) >>> 1; 295 double midVal = array[mid]; 296 297 if (midVal < value) { 298 lo = mid + 1; 299 } else if (midVal > value) { 300 hi = mid - 1; 301 } else if (midVal != 0 && midVal == value) { 302 return mid; // value found 303 } else { // Either midVal and value are == 0 or at least one is NaN 304 long midValBits = Double.doubleToLongBits(midVal); 305 long valueBits = Double.doubleToLongBits(value); 306 307 if (midValBits < valueBits) { 308 lo = mid + 1; // (-0.0, 0.0) or (not NaN, NaN); midVal < val 309 } else if (midValBits > valueBits) { 310 hi = mid - 1; // (0.0, -0.0) or (NaN, not NaN); midVal > val 311 } else { 312 return mid; // bit patterns are equal; value found 313 } 314 } 315 } 316 return ~lo; // value not present 317 } 318 319 /** 320 * Performs a binary search for {@code value} in the ascending sorted array {@code array}. 321 * Searching in an unsorted array has an undefined result. It's also undefined which element 322 * is found if there are multiple occurrences of the same element. 323 * 324 * @param array the sorted array to search. 325 * @param value the element to find. 326 * @return the non-negative index of the element, or a negative index which 327 * is {@code -index - 1} where the element would be inserted. 328 */ 329 public static int binarySearch(float[] array, float value) { 330 return binarySearch(array, 0, array.length, value); 331 } 332 333 /** 334 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 335 * in the range specified by fromIndex (inclusive) and toIndex (exclusive). 336 * Searching in an unsorted array has an undefined result. It's also undefined which element 337 * is found if there are multiple occurrences of the same element. 338 * 339 * @param array the sorted array to search. 340 * @param startIndex the inclusive start index. 341 * @param endIndex the exclusive start index. 342 * @param value the element to find. 343 * @return the non-negative index of the element, or a negative index which 344 * is {@code -index - 1} where the element would be inserted. 345 * @throws IllegalArgumentException if {@code startIndex > endIndex} 346 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 347 * @since 1.6 348 */ 349 public static int binarySearch(float[] array, int startIndex, int endIndex, float value) { 350 checkBinarySearchBounds(startIndex, endIndex, array.length); 351 int lo = startIndex; 352 int hi = endIndex - 1; 353 354 while (lo <= hi) { 355 int mid = (lo + hi) >>> 1; 356 float midVal = array[mid]; 357 358 if (midVal < value) { 359 lo = mid + 1; 360 } else if (midVal > value) { 361 hi = mid - 1; 362 } else if (midVal != 0 && midVal == value) { 363 return mid; // value found 364 } else { // Either midVal and value are == 0 or at least one is NaN 365 int midValBits = Float.floatToIntBits(midVal); 366 int valueBits = Float.floatToIntBits(value); 367 368 if (midValBits < valueBits) { 369 lo = mid + 1; // (-0.0, 0.0) or (not NaN, NaN); midVal < val 370 } else if (midValBits > valueBits) { 371 hi = mid - 1; // (0.0, -0.0) or (NaN, not NaN); midVal > val 372 } else { 373 return mid; // bit patterns are equal; value found 374 } 375 } 376 } 377 return ~lo; // value not present 378 } 379 380 /** 381 * Performs a binary search for {@code value} in the ascending sorted array {@code array}. 382 * Searching in an unsorted array has an undefined result. It's also undefined which element 383 * is found if there are multiple occurrences of the same element. 384 * 385 * @param array the sorted array to search. 386 * @param value the element to find. 387 * @return the non-negative index of the element, or a negative index which 388 * is {@code -index - 1} where the element would be inserted. 389 */ 390 public static int binarySearch(int[] array, int value) { 391 return binarySearch(array, 0, array.length, value); 392 } 393 394 /** 395 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 396 * in the range specified by fromIndex (inclusive) and toIndex (exclusive). 397 * Searching in an unsorted array has an undefined result. It's also undefined which element 398 * is found if there are multiple occurrences of the same element. 399 * 400 * @param array the sorted array to search. 401 * @param startIndex the inclusive start index. 402 * @param endIndex the exclusive start index. 403 * @param value the element to find. 404 * @return the non-negative index of the element, or a negative index which 405 * is {@code -index - 1} where the element would be inserted. 406 * @throws IllegalArgumentException if {@code startIndex > endIndex} 407 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 408 * @since 1.6 409 */ 410 public static int binarySearch(int[] array, int startIndex, int endIndex, int value) { 411 checkBinarySearchBounds(startIndex, endIndex, array.length); 412 int lo = startIndex; 413 int hi = endIndex - 1; 414 415 while (lo <= hi) { 416 int mid = (lo + hi) >>> 1; 417 int midVal = array[mid]; 418 419 if (midVal < value) { 420 lo = mid + 1; 421 } else if (midVal > value) { 422 hi = mid - 1; 423 } else { 424 return mid; // value found 425 } 426 } 427 return ~lo; // value not present 428 } 429 430 /** 431 * Performs a binary search for {@code value} in the ascending sorted array {@code array}. 432 * Searching in an unsorted array has an undefined result. It's also undefined which element 433 * is found if there are multiple occurrences of the same element. 434 * 435 * @param array the sorted array to search. 436 * @param value the element to find. 437 * @return the non-negative index of the element, or a negative index which 438 * is {@code -index - 1} where the element would be inserted. 439 */ 440 public static int binarySearch(long[] array, long value) { 441 return binarySearch(array, 0, array.length, value); 442 } 443 444 /** 445 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 446 * in the range specified by fromIndex (inclusive) and toIndex (exclusive). 447 * Searching in an unsorted array has an undefined result. It's also undefined which element 448 * is found if there are multiple occurrences of the same element. 449 * 450 * @param array the sorted array to search. 451 * @param startIndex the inclusive start index. 452 * @param endIndex the exclusive start index. 453 * @param value the element to find. 454 * @return the non-negative index of the element, or a negative index which 455 * is {@code -index - 1} where the element would be inserted. 456 * @throws IllegalArgumentException if {@code startIndex > endIndex} 457 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 458 * @since 1.6 459 */ 460 public static int binarySearch(long[] array, int startIndex, int endIndex, long value) { 461 checkBinarySearchBounds(startIndex, endIndex, array.length); 462 int lo = startIndex; 463 int hi = endIndex - 1; 464 465 while (lo <= hi) { 466 int mid = (lo + hi) >>> 1; 467 long midVal = array[mid]; 468 469 if (midVal < value) { 470 lo = mid + 1; 471 } else if (midVal > value) { 472 hi = mid - 1; 473 } else { 474 return mid; // value found 475 } 476 } 477 return ~lo; // value not present 478 } 479 480 /** 481 * Performs a binary search for {@code value} in the ascending sorted array {@code array}. 482 * Searching in an unsorted array has an undefined result. It's also undefined which element 483 * is found if there are multiple occurrences of the same element. 484 * 485 * @param array the sorted array to search. 486 * @param value the element to find. 487 * @return the non-negative index of the element, or a negative index which 488 * is {@code -index - 1} where the element would be inserted. 489 * @throws ClassCastException 490 * if an element in the array or the search element does not 491 * implement {@code Comparable}, or cannot be compared to each other. 492 */ 493 public static int binarySearch(Object[] array, Object value) { 494 return binarySearch(array, 0, array.length, value); 495 } 496 497 /** 498 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 499 * in the range specified by fromIndex (inclusive) and toIndex (exclusive). 500 * Searching in an unsorted array has an undefined result. It's also undefined which element 501 * is found if there are multiple occurrences of the same element. 502 * 503 * @param array the sorted array to search. 504 * @param startIndex the inclusive start index. 505 * @param endIndex the exclusive start index. 506 * @param value the element to find. 507 * @return the non-negative index of the element, or a negative index which 508 * is {@code -index - 1} where the element would be inserted. 509 * @throws ClassCastException 510 * if an element in the array or the search element does not 511 * implement {@code Comparable}, or cannot be compared to each other. 512 * @throws IllegalArgumentException if {@code startIndex > endIndex} 513 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 514 * @since 1.6 515 */ 516 public static int binarySearch(Object[] array, int startIndex, int endIndex, Object value) { 517 checkBinarySearchBounds(startIndex, endIndex, array.length); 518 int lo = startIndex; 519 int hi = endIndex - 1; 520 521 while (lo <= hi) { 522 int mid = (lo + hi) >>> 1; 523 @SuppressWarnings("unchecked") 524 int midValCmp = ((Comparable) array[mid]).compareTo(value); 525 526 if (midValCmp < 0) { 527 lo = mid + 1; 528 } else if (midValCmp > 0) { 529 hi = mid - 1; 530 } else { 531 return mid; // value found 532 } 533 } 534 return ~lo; // value not present 535 } 536 537 /** 538 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 539 * using {@code comparator} to compare elements. 540 * Searching in an unsorted array has an undefined result. It's also undefined which element 541 * is found if there are multiple occurrences of the same element. 542 * 543 * @param array the sorted array to search. 544 * @param value the element to find. 545 * @param comparator the {@code Comparator} used to compare the elements. 546 * @return the non-negative index of the element, or a negative index which 547 * is {@code -index - 1} where the element would be inserted. 548 * @throws ClassCastException 549 * if an element in the array or the search element does not 550 * implement {@code Comparable}, or cannot be compared to each other. 551 */ 552 public static <T> int binarySearch(T[] array, T value, Comparator<? super T> comparator) { 553 return binarySearch(array, 0, array.length, value, comparator); 554 } 555 556 /** 557 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 558 * in the range specified by fromIndex (inclusive) and toIndex (exclusive), 559 * using {@code comparator} to compare elements. 560 * Searching in an unsorted array has an undefined result. It's also undefined which element 561 * is found if there are multiple occurrences of the same element. 562 * 563 * @param array the sorted array to search. 564 * @param startIndex the inclusive start index. 565 * @param endIndex the exclusive start index. 566 * @param value the element to find. 567 * @param comparator the {@code Comparator} used to compare the elements. 568 * @return the non-negative index of the element, or a negative index which 569 * is {@code -index - 1} where the element would be inserted. 570 * @throws ClassCastException 571 * if an element in the array or the search element does not 572 * implement {@code Comparable}, or cannot be compared to each other. 573 * @throws IllegalArgumentException if {@code startIndex > endIndex} 574 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 575 * @since 1.6 576 */ 577 public static <T> int binarySearch(T[] array, int startIndex, int endIndex, T value, 578 Comparator<? super T> comparator) { 579 if (comparator == null) { 580 return binarySearch(array, startIndex, endIndex, value); 581 } 582 583 checkBinarySearchBounds(startIndex, endIndex, array.length); 584 int lo = startIndex; 585 int hi = endIndex - 1; 586 587 while (lo <= hi) { 588 int mid = (lo + hi) >>> 1; 589 int midValCmp = comparator.compare(array[mid], value); 590 591 if (midValCmp < 0) { 592 lo = mid + 1; 593 } else if (midValCmp > 0) { 594 hi = mid - 1; 595 } else { 596 return mid; // value found 597 } 598 } 599 return ~lo; // value not present 600 } 601 602 /** 603 * Performs a binary search for {@code value} in the ascending sorted array {@code array}. 604 * Searching in an unsorted array has an undefined result. It's also undefined which element 605 * is found if there are multiple occurrences of the same element. 606 * 607 * @param array the sorted array to search. 608 * @param value the element to find. 609 * @return the non-negative index of the element, or a negative index which 610 * is {@code -index - 1} where the element would be inserted. 611 */ 612 public static int binarySearch(short[] array, short value) { 613 return binarySearch(array, 0, array.length, value); 614 } 615 616 /** 617 * Performs a binary search for {@code value} in the ascending sorted array {@code array}, 618 * in the range specified by fromIndex (inclusive) and toIndex (exclusive). 619 * Searching in an unsorted array has an undefined result. It's also undefined which element 620 * is found if there are multiple occurrences of the same element. 621 * 622 * @param array the sorted array to search. 623 * @param startIndex the inclusive start index. 624 * @param endIndex the exclusive start index. 625 * @param value the element to find. 626 * @return the non-negative index of the element, or a negative index which 627 * is {@code -index - 1} where the element would be inserted. 628 * @throws IllegalArgumentException if {@code startIndex > endIndex} 629 * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length} 630 * @since 1.6 631 */ 632 public static int binarySearch(short[] array, int startIndex, int endIndex, short value) { 633 checkBinarySearchBounds(startIndex, endIndex, array.length); 634 int lo = startIndex; 635 int hi = endIndex - 1; 636 637 while (lo <= hi) { 638 int mid = (lo + hi) >>> 1; 639 short midVal = array[mid]; 640 641 if (midVal < value) { 642 lo = mid + 1; 643 } else if (midVal > value) { 644 hi = mid - 1; 645 } else { 646 return mid; // value found 647 } 648 } 649 return ~lo; // value not present 650 } 651 652 private static void checkBinarySearchBounds(int startIndex, int endIndex, int length) { 653 if (startIndex > endIndex) { 654 throw new IllegalArgumentException(); 655 } 656 if (startIndex < 0 || endIndex > length) { 657 throw new ArrayIndexOutOfBoundsException(); 658 } 659 } 660 661 /** 662 * Fills the specified array with the specified element. 663 * 664 * @param array 665 * the {@code byte} array to fill. 666 * @param value 667 * the {@code byte} element. 668 */ 669 public static void fill(byte[] array, byte value) { 670 for (int i = 0; i < array.length; i++) { 671 array[i] = value; 672 } 673 } 674 675 /** 676 * Fills the specified range in the array with the specified element. 677 * 678 * @param array 679 * the {@code byte} array to fill. 680 * @param start 681 * the first index to fill. 682 * @param end 683 * the last + 1 index to fill. 684 * @param value 685 * the {@code byte} element. 686 * @throws IllegalArgumentException 687 * if {@code start > end}. 688 * @throws ArrayIndexOutOfBoundsException 689 * if {@code start < 0} or {@code end > array.length}. 690 */ 691 public static void fill(byte[] array, int start, int end, byte value) { 692 Arrays.checkStartAndEnd(array.length, start, end); 693 for (int i = start; i < end; i++) { 694 array[i] = value; 695 } 696 } 697 698 /** 699 * Fills the specified array with the specified element. 700 * 701 * @param array 702 * the {@code short} array to fill. 703 * @param value 704 * the {@code short} element. 705 */ 706 public static void fill(short[] array, short value) { 707 for (int i = 0; i < array.length; i++) { 708 array[i] = value; 709 } 710 } 711 712 /** 713 * Fills the specified range in the array with the specified element. 714 * 715 * @param array 716 * the {@code short} array to fill. 717 * @param start 718 * the first index to fill. 719 * @param end 720 * the last + 1 index to fill. 721 * @param value 722 * the {@code short} element. 723 * @throws IllegalArgumentException 724 * if {@code start > end}. 725 * @throws ArrayIndexOutOfBoundsException 726 * if {@code start < 0} or {@code end > array.length}. 727 */ 728 public static void fill(short[] array, int start, int end, short value) { 729 Arrays.checkStartAndEnd(array.length, start, end); 730 for (int i = start; i < end; i++) { 731 array[i] = value; 732 } 733 } 734 735 /** 736 * Fills the specified array with the specified element. 737 * 738 * @param array 739 * the {@code char} array to fill. 740 * @param value 741 * the {@code char} element. 742 */ 743 public static void fill(char[] array, char value) { 744 for (int i = 0; i < array.length; i++) { 745 array[i] = value; 746 } 747 } 748 749 /** 750 * Fills the specified range in the array with the specified element. 751 * 752 * @param array 753 * the {@code char} array to fill. 754 * @param start 755 * the first index to fill. 756 * @param end 757 * the last + 1 index to fill. 758 * @param value 759 * the {@code char} element. 760 * @throws IllegalArgumentException 761 * if {@code start > end}. 762 * @throws ArrayIndexOutOfBoundsException 763 * if {@code start < 0} or {@code end > array.length}. 764 */ 765 public static void fill(char[] array, int start, int end, char value) { 766 Arrays.checkStartAndEnd(array.length, start, end); 767 for (int i = start; i < end; i++) { 768 array[i] = value; 769 } 770 } 771 772 /** 773 * Fills the specified array with the specified element. 774 * 775 * @param array 776 * the {@code int} array to fill. 777 * @param value 778 * the {@code int} element. 779 */ 780 public static void fill(int[] array, int value) { 781 for (int i = 0; i < array.length; i++) { 782 array[i] = value; 783 } 784 } 785 786 /** 787 * Fills the specified range in the array with the specified element. 788 * 789 * @param array 790 * the {@code int} array to fill. 791 * @param start 792 * the first index to fill. 793 * @param end 794 * the last + 1 index to fill. 795 * @param value 796 * the {@code int} element. 797 * @throws IllegalArgumentException 798 * if {@code start > end}. 799 * @throws ArrayIndexOutOfBoundsException 800 * if {@code start < 0} or {@code end > array.length}. 801 */ 802 public static void fill(int[] array, int start, int end, int value) { 803 Arrays.checkStartAndEnd(array.length, start, end); 804 for (int i = start; i < end; i++) { 805 array[i] = value; 806 } 807 } 808 809 /** 810 * Fills the specified array with the specified element. 811 * 812 * @param array 813 * the {@code long} array to fill. 814 * @param value 815 * the {@code long} element. 816 */ 817 public static void fill(long[] array, long value) { 818 for (int i = 0; i < array.length; i++) { 819 array[i] = value; 820 } 821 } 822 823 /** 824 * Fills the specified range in the array with the specified element. 825 * 826 * @param array 827 * the {@code long} array to fill. 828 * @param start 829 * the first index to fill. 830 * @param end 831 * the last + 1 index to fill. 832 * @param value 833 * the {@code long} element. 834 * @throws IllegalArgumentException 835 * if {@code start > end}. 836 * @throws ArrayIndexOutOfBoundsException 837 * if {@code start < 0} or {@code end > array.length}. 838 */ 839 public static void fill(long[] array, int start, int end, long value) { 840 Arrays.checkStartAndEnd(array.length, start, end); 841 for (int i = start; i < end; i++) { 842 array[i] = value; 843 } 844 } 845 846 /** 847 * Fills the specified array with the specified element. 848 * 849 * @param array 850 * the {@code float} array to fill. 851 * @param value 852 * the {@code float} element. 853 */ 854 public static void fill(float[] array, float value) { 855 for (int i = 0; i < array.length; i++) { 856 array[i] = value; 857 } 858 } 859 860 /** 861 * Fills the specified range in the array with the specified element. 862 * 863 * @param array 864 * the {@code float} array to fill. 865 * @param start 866 * the first index to fill. 867 * @param end 868 * the last + 1 index to fill. 869 * @param value 870 * the {@code float} element. 871 * @throws IllegalArgumentException 872 * if {@code start > end}. 873 * @throws ArrayIndexOutOfBoundsException 874 * if {@code start < 0} or {@code end > array.length}. 875 */ 876 public static void fill(float[] array, int start, int end, float value) { 877 Arrays.checkStartAndEnd(array.length, start, end); 878 for (int i = start; i < end; i++) { 879 array[i] = value; 880 } 881 } 882 883 /** 884 * Fills the specified array with the specified element. 885 * 886 * @param array 887 * the {@code double} array to fill. 888 * @param value 889 * the {@code double} element. 890 */ 891 public static void fill(double[] array, double value) { 892 for (int i = 0; i < array.length; i++) { 893 array[i] = value; 894 } 895 } 896 897 /** 898 * Fills the specified range in the array with the specified element. 899 * 900 * @param array 901 * the {@code double} array to fill. 902 * @param start 903 * the first index to fill. 904 * @param end 905 * the last + 1 index to fill. 906 * @param value 907 * the {@code double} element. 908 * @throws IllegalArgumentException 909 * if {@code start > end}. 910 * @throws ArrayIndexOutOfBoundsException 911 * if {@code start < 0} or {@code end > array.length}. 912 */ 913 public static void fill(double[] array, int start, int end, double value) { 914 Arrays.checkStartAndEnd(array.length, start, end); 915 for (int i = start; i < end; i++) { 916 array[i] = value; 917 } 918 } 919 920 /** 921 * Fills the specified array with the specified element. 922 * 923 * @param array 924 * the {@code boolean} array to fill. 925 * @param value 926 * the {@code boolean} element. 927 */ 928 public static void fill(boolean[] array, boolean value) { 929 for (int i = 0; i < array.length; i++) { 930 array[i] = value; 931 } 932 } 933 934 /** 935 * Fills the specified range in the array with the specified element. 936 * 937 * @param array 938 * the {@code boolean} array to fill. 939 * @param start 940 * the first index to fill. 941 * @param end 942 * the last + 1 index to fill. 943 * @param value 944 * the {@code boolean} element. 945 * @throws IllegalArgumentException 946 * if {@code start > end}. 947 * @throws ArrayIndexOutOfBoundsException 948 * if {@code start < 0} or {@code end > array.length}. 949 */ 950 public static void fill(boolean[] array, int start, int end, boolean value) { 951 Arrays.checkStartAndEnd(array.length, start, end); 952 for (int i = start; i < end; i++) { 953 array[i] = value; 954 } 955 } 956 957 /** 958 * Fills the specified array with the specified element. 959 * 960 * @param array 961 * the {@code Object} array to fill. 962 * @param value 963 * the {@code Object} element. 964 */ 965 public static void fill(Object[] array, Object value) { 966 for (int i = 0; i < array.length; i++) { 967 array[i] = value; 968 } 969 } 970 971 /** 972 * Fills the specified range in the array with the specified element. 973 * 974 * @param array 975 * the {@code Object} array to fill. 976 * @param start 977 * the first index to fill. 978 * @param end 979 * the last + 1 index to fill. 980 * @param value 981 * the {@code Object} element. 982 * @throws IllegalArgumentException 983 * if {@code start > end}. 984 * @throws ArrayIndexOutOfBoundsException 985 * if {@code start < 0} or {@code end > array.length}. 986 */ 987 public static void fill(Object[] array, int start, int end, Object value) { 988 Arrays.checkStartAndEnd(array.length, start, end); 989 for (int i = start; i < end; i++) { 990 array[i] = value; 991 } 992 } 993 994 /** 995 * Returns a hash code based on the contents of the given array. For any two 996 * {@code boolean} arrays {@code a} and {@code b}, if 997 * {@code Arrays.equals(a, b)} returns {@code true}, it means 998 * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}. 999 * <p> 1000 * The value returned by this method is the same value as the 1001 * {@link List#hashCode()} method which is invoked on a {@link List} 1002 * containing a sequence of {@link Boolean} instances representing the 1003 * elements of array in the same order. If the array is {@code null}, the return 1004 * value is 0. 1005 * 1006 * @param array 1007 * the array whose hash code to compute. 1008 * @return the hash code for {@code array}. 1009 */ 1010 public static int hashCode(boolean[] array) { 1011 if (array == null) { 1012 return 0; 1013 } 1014 int hashCode = 1; 1015 for (boolean element : array) { 1016 // 1231, 1237 are hash code values for boolean value 1017 hashCode = 31 * hashCode + (element ? 1231 : 1237); 1018 } 1019 return hashCode; 1020 } 1021 1022 /** 1023 * Returns a hash code based on the contents of the given array. For any two 1024 * not-null {@code int} arrays {@code a} and {@code b}, if 1025 * {@code Arrays.equals(a, b)} returns {@code true}, it means 1026 * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}. 1027 * <p> 1028 * The value returned by this method is the same value as the 1029 * {@link List#hashCode()} method which is invoked on a {@link List} 1030 * containing a sequence of {@link Integer} instances representing the 1031 * elements of array in the same order. If the array is {@code null}, the return 1032 * value is 0. 1033 * 1034 * @param array 1035 * the array whose hash code to compute. 1036 * @return the hash code for {@code array}. 1037 */ 1038 public static int hashCode(int[] array) { 1039 if (array == null) { 1040 return 0; 1041 } 1042 int hashCode = 1; 1043 for (int element : array) { 1044 // the hash code value for integer value is integer value itself 1045 hashCode = 31 * hashCode + element; 1046 } 1047 return hashCode; 1048 } 1049 1050 /** 1051 * Returns a hash code based on the contents of the given array. For any two 1052 * {@code short} arrays {@code a} and {@code b}, if 1053 * {@code Arrays.equals(a, b)} returns {@code true}, it means 1054 * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}. 1055 * <p> 1056 * The value returned by this method is the same value as the 1057 * {@link List#hashCode()} method which is invoked on a {@link List} 1058 * containing a sequence of {@link Short} instances representing the 1059 * elements of array in the same order. If the array is {@code null}, the return 1060 * value is 0. 1061 * 1062 * @param array 1063 * the array whose hash code to compute. 1064 * @return the hash code for {@code array}. 1065 */ 1066 public static int hashCode(short[] array) { 1067 if (array == null) { 1068 return 0; 1069 } 1070 int hashCode = 1; 1071 for (short element : array) { 1072 // the hash code value for short value is its integer value 1073 hashCode = 31 * hashCode + element; 1074 } 1075 return hashCode; 1076 } 1077 1078 /** 1079 * Returns a hash code based on the contents of the given array. For any two 1080 * {@code char} arrays {@code a} and {@code b}, if 1081 * {@code Arrays.equals(a, b)} returns {@code true}, it means 1082 * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}. 1083 * <p> 1084 * The value returned by this method is the same value as the 1085 * {@link List#hashCode()} method which is invoked on a {@link List} 1086 * containing a sequence of {@link Character} instances representing the 1087 * elements of array in the same order. If the array is {@code null}, the return 1088 * value is 0. 1089 * 1090 * @param array 1091 * the array whose hash code to compute. 1092 * @return the hash code for {@code array}. 1093 */ 1094 public static int hashCode(char[] array) { 1095 if (array == null) { 1096 return 0; 1097 } 1098 int hashCode = 1; 1099 for (char element : array) { 1100 // the hash code value for char value is its integer value 1101 hashCode = 31 * hashCode + element; 1102 } 1103 return hashCode; 1104 } 1105 1106 /** 1107 * Returns a hash code based on the contents of the given array. For any two 1108 * {@code byte} arrays {@code a} and {@code b}, if 1109 * {@code Arrays.equals(a, b)} returns {@code true}, it means 1110 * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}. 1111 * <p> 1112 * The value returned by this method is the same value as the 1113 * {@link List#hashCode()} method which is invoked on a {@link List} 1114 * containing a sequence of {@link Byte} instances representing the 1115 * elements of array in the same order. If the array is {@code null}, the return 1116 * value is 0. 1117 * 1118 * @param array 1119 * the array whose hash code to compute. 1120 * @return the hash code for {@code array}. 1121 */ 1122 public static int hashCode(byte[] array) { 1123 if (array == null) { 1124 return 0; 1125 } 1126 int hashCode = 1; 1127 for (byte element : array) { 1128 // the hash code value for byte value is its integer value 1129 hashCode = 31 * hashCode + element; 1130 } 1131 return hashCode; 1132 } 1133 1134 /** 1135 * Returns a hash code based on the contents of the given array. For any two 1136 * {@code long} arrays {@code a} and {@code b}, if 1137 * {@code Arrays.equals(a, b)} returns {@code true}, it means 1138 * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}. 1139 * <p> 1140 * The value returned by this method is the same value as the 1141 * {@link List#hashCode()} method which is invoked on a {@link List} 1142 * containing a sequence of {@link Long} instances representing the 1143 * elements of array in the same order. If the array is {@code null}, the return 1144 * value is 0. 1145 * 1146 * @param array 1147 * the array whose hash code to compute. 1148 * @return the hash code for {@code array}. 1149 */ 1150 public static int hashCode(long[] array) { 1151 if (array == null) { 1152 return 0; 1153 } 1154 int hashCode = 1; 1155 for (long elementValue : array) { 1156 /* 1157 * the hash code value for long value is (int) (value ^ (value >>> 1158 * 32)) 1159 */ 1160 hashCode = 31 * hashCode 1161 + (int) (elementValue ^ (elementValue >>> 32)); 1162 } 1163 return hashCode; 1164 } 1165 1166 /** 1167 * Returns a hash code based on the contents of the given array. For any two 1168 * {@code float} arrays {@code a} and {@code b}, if 1169 * {@code Arrays.equals(a, b)} returns {@code true}, it means 1170 * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}. 1171 * <p> 1172 * The value returned by this method is the same value as the 1173 * {@link List#hashCode()} method which is invoked on a {@link List} 1174 * containing a sequence of {@link Float} instances representing the 1175 * elements of array in the same order. If the array is {@code null}, the return 1176 * value is 0. 1177 * 1178 * @param array 1179 * the array whose hash code to compute. 1180 * @return the hash code for {@code array}. 1181 */ 1182 public static int hashCode(float[] array) { 1183 if (array == null) { 1184 return 0; 1185 } 1186 int hashCode = 1; 1187 for (float element : array) { 1188 /* 1189 * the hash code value for float value is 1190 * Float.floatToIntBits(value) 1191 */ 1192 hashCode = 31 * hashCode + Float.floatToIntBits(element); 1193 } 1194 return hashCode; 1195 } 1196 1197 /** 1198 * Returns a hash code based on the contents of the given array. For any two 1199 * {@code double} arrays {@code a} and {@code b}, if 1200 * {@code Arrays.equals(a, b)} returns {@code true}, it means 1201 * that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}. 1202 * <p> 1203 * The value returned by this method is the same value as the 1204 * {@link List#hashCode()} method which is invoked on a {@link List} 1205 * containing a sequence of {@link Double} instances representing the 1206 * elements of array in the same order. If the array is {@code null}, the return 1207 * value is 0. 1208 * 1209 * @param array 1210 * the array whose hash code to compute. 1211 * @return the hash code for {@code array}. 1212 */ 1213 public static int hashCode(double[] array) { 1214 if (array == null) { 1215 return 0; 1216 } 1217 int hashCode = 1; 1218 1219 for (double element : array) { 1220 long v = Double.doubleToLongBits(element); 1221 /* 1222 * the hash code value for double value is (int) (v ^ (v >>> 32)) 1223 * where v = Double.doubleToLongBits(value) 1224 */ 1225 hashCode = 31 * hashCode + (int) (v ^ (v >>> 32)); 1226 } 1227 return hashCode; 1228 } 1229 1230 /** 1231 * Returns a hash code based on the contents of the given array. If the 1232 * array contains other arrays as its elements, the hash code is based on 1233 * their identities not their contents. So it is acceptable to invoke this 1234 * method on an array that contains itself as an element, either directly or 1235 * indirectly. 1236 * <p> 1237 * For any two arrays {@code a} and {@code b}, if 1238 * {@code Arrays.equals(a, b)} returns {@code true}, it means 1239 * that the return value of {@code Arrays.hashCode(a)} equals 1240 * {@code Arrays.hashCode(b)}. 1241 * <p> 1242 * The value returned by this method is the same value as the method 1243 * Arrays.asList(array).hashCode(). If the array is {@code null}, the return value 1244 * is 0. 1245 * 1246 * @param array 1247 * the array whose hash code to compute. 1248 * @return the hash code for {@code array}. 1249 */ 1250 public static int hashCode(Object[] array) { 1251 if (array == null) { 1252 return 0; 1253 } 1254 int hashCode = 1; 1255 for (Object element : array) { 1256 int elementHashCode; 1257 1258 if (element == null) { 1259 elementHashCode = 0; 1260 } else { 1261 elementHashCode = (element).hashCode(); 1262 } 1263 hashCode = 31 * hashCode + elementHashCode; 1264 } 1265 return hashCode; 1266 } 1267 1268 /** 1269 * Returns a hash code based on the "deep contents" of the given array. If 1270 * the array contains other arrays as its elements, the hash code is based 1271 * on their contents not their identities. So it is not acceptable to invoke 1272 * this method on an array that contains itself as an element, either 1273 * directly or indirectly. 1274 * <p> 1275 * For any two arrays {@code a} and {@code b}, if 1276 * {@code Arrays.deepEquals(a, b)} returns {@code true}, it 1277 * means that the return value of {@code Arrays.deepHashCode(a)} equals 1278 * {@code Arrays.deepHashCode(b)}. 1279 * <p> 1280 * The computation of the value returned by this method is similar to that 1281 * of the value returned by {@link List#hashCode()} invoked on a 1282 * {@link List} containing a sequence of instances representing the 1283 * elements of array in the same order. The difference is: If an element e 1284 * of array is itself an array, its hash code is computed by calling the 1285 * appropriate overloading of {@code Arrays.hashCode(e)} if e is an array of a 1286 * primitive type, or by calling {@code Arrays.deepHashCode(e)} recursively if e is 1287 * an array of a reference type. The value returned by this method is the 1288 * same value as the method {@code Arrays.asList(array).hashCode()}. If the array is 1289 * {@code null}, the return value is 0. 1290 * 1291 * @param array 1292 * the array whose hash code to compute. 1293 * @return the hash code for {@code array}. 1294 */ 1295 public static int deepHashCode(Object[] array) { 1296 if (array == null) { 1297 return 0; 1298 } 1299 int hashCode = 1; 1300 for (Object element : array) { 1301 int elementHashCode = deepHashCodeElement(element); 1302 hashCode = 31 * hashCode + elementHashCode; 1303 } 1304 return hashCode; 1305 } 1306 1307 private static int deepHashCodeElement(Object element) { 1308 Class<?> cl; 1309 if (element == null) { 1310 return 0; 1311 } 1312 1313 cl = element.getClass().getComponentType(); 1314 1315 if (cl == null) { 1316 return element.hashCode(); 1317 } 1318 1319 /* 1320 * element is an array 1321 */ 1322 if (!cl.isPrimitive()) { 1323 return deepHashCode((Object[]) element); 1324 } 1325 if (cl.equals(int.class)) { 1326 return hashCode((int[]) element); 1327 } 1328 if (cl.equals(char.class)) { 1329 return hashCode((char[]) element); 1330 } 1331 if (cl.equals(boolean.class)) { 1332 return hashCode((boolean[]) element); 1333 } 1334 if (cl.equals(byte.class)) { 1335 return hashCode((byte[]) element); 1336 } 1337 if (cl.equals(long.class)) { 1338 return hashCode((long[]) element); 1339 } 1340 if (cl.equals(float.class)) { 1341 return hashCode((float[]) element); 1342 } 1343 if (cl.equals(double.class)) { 1344 return hashCode((double[]) element); 1345 } 1346 return hashCode((short[]) element); 1347 } 1348 1349 /** 1350 * Compares the two arrays. 1351 * 1352 * @param array1 1353 * the first {@code byte} array. 1354 * @param array2 1355 * the second {@code byte} array. 1356 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1357 * same length and the elements at each index in the two arrays are 1358 * equal, {@code false} otherwise. 1359 */ 1360 public static boolean equals(byte[] array1, byte[] array2) { 1361 if (array1 == array2) { 1362 return true; 1363 } 1364 if (array1 == null || array2 == null || array1.length != array2.length) { 1365 return false; 1366 } 1367 for (int i = 0; i < array1.length; i++) { 1368 if (array1[i] != array2[i]) { 1369 return false; 1370 } 1371 } 1372 return true; 1373 } 1374 1375 /** 1376 * Compares the two arrays. 1377 * 1378 * @param array1 1379 * the first {@code short} array. 1380 * @param array2 1381 * the second {@code short} array. 1382 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1383 * same length and the elements at each index in the two arrays are 1384 * equal, {@code false} otherwise. 1385 */ 1386 public static boolean equals(short[] array1, short[] array2) { 1387 if (array1 == array2) { 1388 return true; 1389 } 1390 if (array1 == null || array2 == null || array1.length != array2.length) { 1391 return false; 1392 } 1393 for (int i = 0; i < array1.length; i++) { 1394 if (array1[i] != array2[i]) { 1395 return false; 1396 } 1397 } 1398 return true; 1399 } 1400 1401 /** 1402 * Compares the two arrays. 1403 * 1404 * @param array1 1405 * the first {@code char} array. 1406 * @param array2 1407 * the second {@code char} array. 1408 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1409 * same length and the elements at each index in the two arrays are 1410 * equal, {@code false} otherwise. 1411 */ 1412 public static boolean equals(char[] array1, char[] array2) { 1413 if (array1 == array2) { 1414 return true; 1415 } 1416 if (array1 == null || array2 == null || array1.length != array2.length) { 1417 return false; 1418 } 1419 for (int i = 0; i < array1.length; i++) { 1420 if (array1[i] != array2[i]) { 1421 return false; 1422 } 1423 } 1424 return true; 1425 } 1426 1427 /** 1428 * Compares the two arrays. 1429 * 1430 * @param array1 1431 * the first {@code int} array. 1432 * @param array2 1433 * the second {@code int} array. 1434 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1435 * same length and the elements at each index in the two arrays are 1436 * equal, {@code false} otherwise. 1437 */ 1438 public static boolean equals(int[] array1, int[] array2) { 1439 if (array1 == array2) { 1440 return true; 1441 } 1442 if (array1 == null || array2 == null || array1.length != array2.length) { 1443 return false; 1444 } 1445 for (int i = 0; i < array1.length; i++) { 1446 if (array1[i] != array2[i]) { 1447 return false; 1448 } 1449 } 1450 return true; 1451 } 1452 1453 /** 1454 * Compares the two arrays. 1455 * 1456 * @param array1 1457 * the first {@code long} array. 1458 * @param array2 1459 * the second {@code long} array. 1460 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1461 * same length and the elements at each index in the two arrays are 1462 * equal, {@code false} otherwise. 1463 */ 1464 public static boolean equals(long[] array1, long[] array2) { 1465 if (array1 == array2) { 1466 return true; 1467 } 1468 if (array1 == null || array2 == null || array1.length != array2.length) { 1469 return false; 1470 } 1471 for (int i = 0; i < array1.length; i++) { 1472 if (array1[i] != array2[i]) { 1473 return false; 1474 } 1475 } 1476 return true; 1477 } 1478 1479 /** 1480 * Compares the two arrays. The values are compared in the same manner as 1481 * {@code Float.equals()}. 1482 * 1483 * @param array1 1484 * the first {@code float} array. 1485 * @param array2 1486 * the second {@code float} array. 1487 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1488 * same length and the elements at each index in the two arrays are 1489 * equal, {@code false} otherwise. 1490 * @see Float#equals(Object) 1491 */ 1492 public static boolean equals(float[] array1, float[] array2) { 1493 if (array1 == array2) { 1494 return true; 1495 } 1496 if (array1 == null || array2 == null || array1.length != array2.length) { 1497 return false; 1498 } 1499 for (int i = 0; i < array1.length; i++) { 1500 if (Float.floatToIntBits(array1[i]) != Float 1501 .floatToIntBits(array2[i])) { 1502 return false; 1503 } 1504 } 1505 return true; 1506 } 1507 1508 /** 1509 * Compares the two arrays. The values are compared in the same manner as 1510 * {@code Double.equals()}. 1511 * 1512 * @param array1 1513 * the first {@code double} array. 1514 * @param array2 1515 * the second {@code double} array. 1516 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1517 * same length and the elements at each index in the two arrays are 1518 * equal, {@code false} otherwise. 1519 * @see Double#equals(Object) 1520 */ 1521 public static boolean equals(double[] array1, double[] array2) { 1522 if (array1 == array2) { 1523 return true; 1524 } 1525 if (array1 == null || array2 == null || array1.length != array2.length) { 1526 return false; 1527 } 1528 for (int i = 0; i < array1.length; i++) { 1529 if (Double.doubleToLongBits(array1[i]) != Double 1530 .doubleToLongBits(array2[i])) { 1531 return false; 1532 } 1533 } 1534 return true; 1535 } 1536 1537 /** 1538 * Compares the two arrays. 1539 * 1540 * @param array1 1541 * the first {@code boolean} array. 1542 * @param array2 1543 * the second {@code boolean} array. 1544 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1545 * same length and the elements at each index in the two arrays are 1546 * equal, {@code false} otherwise. 1547 */ 1548 public static boolean equals(boolean[] array1, boolean[] array2) { 1549 if (array1 == array2) { 1550 return true; 1551 } 1552 if (array1 == null || array2 == null || array1.length != array2.length) { 1553 return false; 1554 } 1555 for (int i = 0; i < array1.length; i++) { 1556 if (array1[i] != array2[i]) { 1557 return false; 1558 } 1559 } 1560 return true; 1561 } 1562 1563 /** 1564 * Compares the two arrays. 1565 * 1566 * @param array1 1567 * the first {@code Object} array. 1568 * @param array2 1569 * the second {@code Object} array. 1570 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1571 * same length and the elements at each index in the two arrays are 1572 * equal according to {@code equals()}, {@code false} otherwise. 1573 */ 1574 public static boolean equals(Object[] array1, Object[] array2) { 1575 if (array1 == array2) { 1576 return true; 1577 } 1578 if (array1 == null || array2 == null || array1.length != array2.length) { 1579 return false; 1580 } 1581 for (int i = 0; i < array1.length; i++) { 1582 Object e1 = array1[i], e2 = array2[i]; 1583 if (!(e1 == null ? e2 == null : e1.equals(e2))) { 1584 return false; 1585 } 1586 } 1587 return true; 1588 } 1589 1590 /** 1591 * Returns {@code true} if the two given arrays are deeply equal to one another. 1592 * Unlike the method {@code equals(Object[] array1, Object[] array2)}, this method 1593 * is appropriate for use for nested arrays of arbitrary depth. 1594 * <p> 1595 * Two array references are considered deeply equal if they are both {@code null}, 1596 * or if they refer to arrays that have the same length and the elements at 1597 * each index in the two arrays are equal. 1598 * <p> 1599 * Two {@code null} elements {@code element1} and {@code element2} are possibly deeply equal if any 1600 * of the following conditions satisfied: 1601 * <p> 1602 * {@code element1} and {@code element2} are both arrays of object reference types, and 1603 * {@code Arrays.deepEquals(element1, element2)} would return {@code true}. 1604 * <p> 1605 * {@code element1} and {@code element2} are arrays of the same primitive type, and the 1606 * appropriate overloading of {@code Arrays.equals(element1, element2)} would return 1607 * {@code true}. 1608 * <p> 1609 * {@code element1 == element2} 1610 * <p> 1611 * {@code element1.equals(element2)} would return {@code true}. 1612 * <p> 1613 * Note that this definition permits {@code null} elements at any depth. 1614 * <p> 1615 * If either of the given arrays contain themselves as elements, the 1616 * behavior of this method is uncertain. 1617 * 1618 * @param array1 1619 * the first {@code Object} array. 1620 * @param array2 1621 * the second {@code Object} array. 1622 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1623 * same length and the elements at each index in the two arrays are 1624 * equal according to {@code equals()}, {@code false} otherwise. 1625 */ 1626 public static boolean deepEquals(Object[] array1, Object[] array2) { 1627 if (array1 == array2) { 1628 return true; 1629 } 1630 if (array1 == null || array2 == null || array1.length != array2.length) { 1631 return false; 1632 } 1633 for (int i = 0; i < array1.length; i++) { 1634 Object e1 = array1[i], e2 = array2[i]; 1635 1636 if (!deepEqualsElements(e1, e2)) { 1637 return false; 1638 } 1639 } 1640 return true; 1641 } 1642 1643 private static boolean deepEqualsElements(Object e1, Object e2) { 1644 Class<?> cl1, cl2; 1645 1646 if (e1 == e2) { 1647 return true; 1648 } 1649 1650 if (e1 == null || e2 == null) { 1651 return false; 1652 } 1653 1654 cl1 = e1.getClass().getComponentType(); 1655 cl2 = e2.getClass().getComponentType(); 1656 1657 if (cl1 != cl2) { 1658 return false; 1659 } 1660 1661 if (cl1 == null) { 1662 return e1.equals(e2); 1663 } 1664 1665 /* 1666 * compare as arrays 1667 */ 1668 if (!cl1.isPrimitive()) { 1669 return deepEquals((Object[]) e1, (Object[]) e2); 1670 } 1671 1672 if (cl1.equals(int.class)) { 1673 return equals((int[]) e1, (int[]) e2); 1674 } 1675 if (cl1.equals(char.class)) { 1676 return equals((char[]) e1, (char[]) e2); 1677 } 1678 if (cl1.equals(boolean.class)) { 1679 return equals((boolean[]) e1, (boolean[]) e2); 1680 } 1681 if (cl1.equals(byte.class)) { 1682 return equals((byte[]) e1, (byte[]) e2); 1683 } 1684 if (cl1.equals(long.class)) { 1685 return equals((long[]) e1, (long[]) e2); 1686 } 1687 if (cl1.equals(float.class)) { 1688 return equals((float[]) e1, (float[]) e2); 1689 } 1690 if (cl1.equals(double.class)) { 1691 return equals((double[]) e1, (double[]) e2); 1692 } 1693 return equals((short[]) e1, (short[]) e2); 1694 } 1695 1696 /** 1697 * Sorts the specified array in ascending numerical order. 1698 * 1699 * @param array 1700 * the {@code byte} array to be sorted. 1701 */ 1702 public static void sort(byte[] array) { 1703 DualPivotQuicksort.sort(array); 1704 } 1705 1706 /** 1707 * Sorts the specified range in the array in ascending numerical order. 1708 * 1709 * @param array 1710 * the {@code byte} array to be sorted. 1711 * @param start 1712 * the start index to sort. 1713 * @param end 1714 * the last + 1 index to sort. 1715 * @throws IllegalArgumentException 1716 * if {@code start > end}. 1717 * @throws ArrayIndexOutOfBoundsException 1718 * if {@code start < 0} or {@code end > array.length}. 1719 */ 1720 public static void sort(byte[] array, int start, int end) { 1721 DualPivotQuicksort.sort(array, start, end); 1722 } 1723 1724 /** 1725 * Checks that the range described by {@code offset} and {@code count} doesn't exceed 1726 * {@code arrayLength}. 1727 * 1728 * @hide 1729 */ 1730 public static void checkOffsetAndCount(int arrayLength, int offset, int count) { 1731 if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) { 1732 throw new ArrayIndexOutOfBoundsException(arrayLength, offset, 1733 count); 1734 } 1735 } 1736 1737 /** 1738 * Checks that the range described by {@code start} and {@code end} doesn't exceed 1739 * {@code len}. 1740 * 1741 * @hide 1742 */ 1743 public static void checkStartAndEnd(int len, int start, int end) { 1744 if (start < 0 || end > len) { 1745 throw new ArrayIndexOutOfBoundsException("start < 0 || end > len." 1746 + " start=" + start + ", end=" + end + ", len=" + len); 1747 } 1748 if (start > end) { 1749 throw new IllegalArgumentException("start > end: " + start + " > " + end); 1750 } 1751 } 1752 1753 /** 1754 * Sorts the specified array in ascending numerical order. 1755 * 1756 * @param array 1757 * the {@code char} array to be sorted. 1758 */ 1759 public static void sort(char[] array) { 1760 DualPivotQuicksort.sort(array); 1761 } 1762 1763 /** 1764 * Sorts the specified range in the array in ascending numerical order. 1765 * 1766 * @param array 1767 * the {@code char} array to be sorted. 1768 * @param start 1769 * the start index to sort. 1770 * @param end 1771 * the last + 1 index to sort. 1772 * @throws IllegalArgumentException 1773 * if {@code start > end}. 1774 * @throws ArrayIndexOutOfBoundsException 1775 * if {@code start < 0} or {@code end > array.length}. 1776 */ 1777 public static void sort(char[] array, int start, int end) { 1778 DualPivotQuicksort.sort(array, start, end); 1779 } 1780 1781 /** 1782 * Sorts the specified array in ascending numerical order. 1783 * 1784 * @param array 1785 * the {@code double} array to be sorted. 1786 * @see #sort(double[], int, int) 1787 */ 1788 public static void sort(double[] array) { 1789 DualPivotQuicksort.sort(array); 1790 } 1791 1792 /** 1793 * Sorts the specified range in the array in ascending numerical order. The 1794 * values are sorted according to the order imposed by {@code Double.compareTo()}. 1795 * 1796 * @param array 1797 * the {@code double} array to be sorted. 1798 * @param start 1799 * the start index to sort. 1800 * @param end 1801 * the last + 1 index to sort. 1802 * @throws IllegalArgumentException 1803 * if {@code start > end}. 1804 * @throws ArrayIndexOutOfBoundsException 1805 * if {@code start < 0} or {@code end > array.length}. 1806 * @see Double#compareTo(Double) 1807 */ 1808 public static void sort(double[] array, int start, int end) { 1809 DualPivotQuicksort.sort(array, start, end); 1810 } 1811 1812 /** 1813 * Sorts the specified array in ascending numerical order. 1814 * 1815 * @param array 1816 * the {@code float} array to be sorted. 1817 * @see #sort(float[], int, int) 1818 */ 1819 public static void sort(float[] array) { 1820 DualPivotQuicksort.sort(array); 1821 } 1822 1823 /** 1824 * Sorts the specified range in the array in ascending numerical order. The 1825 * values are sorted according to the order imposed by {@code Float.compareTo()}. 1826 * 1827 * @param array 1828 * the {@code float} array to be sorted. 1829 * @param start 1830 * the start index to sort. 1831 * @param end 1832 * the last + 1 index to sort. 1833 * @throws IllegalArgumentException 1834 * if {@code start > end}. 1835 * @throws ArrayIndexOutOfBoundsException 1836 * if {@code start < 0} or {@code end > array.length}. 1837 * @see Float#compareTo(Float) 1838 */ 1839 public static void sort(float[] array, int start, int end) { 1840 DualPivotQuicksort.sort(array, start, end); 1841 } 1842 1843 /** 1844 * Sorts the specified array in ascending numerical order. 1845 * 1846 * @param array 1847 * the {@code int} array to be sorted. 1848 */ 1849 public static void sort(int[] array) { 1850 DualPivotQuicksort.sort(array); 1851 } 1852 1853 /** 1854 * Sorts the specified range in the array in ascending numerical order. 1855 * 1856 * @param array 1857 * the {@code int} array to be sorted. 1858 * @param start 1859 * the start index to sort. 1860 * @param end 1861 * the last + 1 index to sort. 1862 * @throws IllegalArgumentException 1863 * if {@code start > end}. 1864 * @throws ArrayIndexOutOfBoundsException 1865 * if {@code start < 0} or {@code end > array.length}. 1866 */ 1867 public static void sort(int[] array, int start, int end) { 1868 DualPivotQuicksort.sort(array, start, end); 1869 } 1870 1871 /** 1872 * Sorts the specified array in ascending numerical order. 1873 * 1874 * @param array 1875 * the {@code long} array to be sorted. 1876 */ 1877 public static void sort(long[] array) { 1878 DualPivotQuicksort.sort(array); 1879 } 1880 1881 /** 1882 * Sorts the specified range in the array in ascending numerical order. 1883 * 1884 * @param array 1885 * the {@code long} array to be sorted. 1886 * @param start 1887 * the start index to sort. 1888 * @param end 1889 * the last + 1 index to sort. 1890 * @throws IllegalArgumentException 1891 * if {@code start > end}. 1892 * @throws ArrayIndexOutOfBoundsException 1893 * if {@code start < 0} or {@code end > array.length}. 1894 */ 1895 public static void sort(long[] array, int start, int end) { 1896 DualPivotQuicksort.sort(array, start, end); 1897 } 1898 1899 /** 1900 * Sorts the specified array in ascending numerical order. 1901 * 1902 * @param array 1903 * the {@code short} array to be sorted. 1904 */ 1905 public static void sort(short[] array) { 1906 DualPivotQuicksort.sort(array); 1907 } 1908 1909 /** 1910 * Sorts the specified range in the array in ascending numerical order. 1911 * 1912 * @param array 1913 * the {@code short} array to be sorted. 1914 * @param start 1915 * the start index to sort. 1916 * @param end 1917 * the last + 1 index to sort. 1918 * @throws IllegalArgumentException 1919 * if {@code start > end}. 1920 * @throws ArrayIndexOutOfBoundsException 1921 * if {@code start < 0} or {@code end > array.length}. 1922 */ 1923 public static void sort(short[] array, int start, int end) { 1924 DualPivotQuicksort.sort(array, start, end); 1925 } 1926 1927// BEGIN android-note 1928 1929 /* 1930 * <p>If this platform has an optimizing VM, check whether ComparableTimSort 1931 * offers any performance benefit over TimSort in conjunction with a 1932 * comparator that returns: 1933 * {@code ((Comparable)first).compareTo(Second)}. 1934 * If not, you are better off deleting ComparableTimSort to eliminate the 1935 * code duplication. In other words, the commented out code below 1936 * is the preferable implementation for sorting arrays of Comparables if it 1937 * offers sufficient performance. 1938 */ 1939 1940// /** 1941// * A comparator that implements the natural order of a group of 1942// * mutually comparable elements. Using this comparator saves us 1943// * from duplicating most of the code in this file (one version for 1944// * Comparables, one for explicit comparators). 1945// */ 1946// private static final Comparator<Object> NATURAL_ORDER = new Comparator<Object>() { 1947// @SuppressWarnings("unchecked") 1948// public int compare(Object first, Object second) { 1949// return ((Comparable<Object>)first).compareTo(second); 1950// } 1951// }; 1952// 1953// public static void sort(Object[] a) { 1954// sort(a, 0, a.length, NATURAL_ORDER); 1955// } 1956// 1957// public static void sort(Object[] a, int fromIndex, int toIndex) { 1958// sort(a, fromIndex, toIndex, NATURAL_ORDER); 1959// } 1960 1961// END android-note 1962 1963 /** 1964 * Sorts the specified array in ascending natural order. 1965 * 1966 * @throws ClassCastException if any element does not implement {@code Comparable}, 1967 * or if {@code compareTo} throws for any pair of elements. 1968 */ 1969 public static void sort(Object[] array) { 1970 ComparableTimSort.sort(array); 1971 } 1972 1973 /** 1974 * Sorts the specified range in the array in ascending natural order. 1975 * 1976 * @param start 1977 * the start index to sort. 1978 * @param end 1979 * the last + 1 index to sort. 1980 * @throws ClassCastException if any element does not implement {@code Comparable}, 1981 * or if {@code compareTo} throws for any pair of elements. 1982 * @throws IllegalArgumentException 1983 * if {@code start > end}. 1984 * @throws ArrayIndexOutOfBoundsException 1985 * if {@code start < 0} or {@code end > array.length}. 1986 */ 1987 public static void sort(Object[] array, int start, int end) { 1988 ComparableTimSort.sort(array, start, end); 1989 } 1990 1991 /** 1992 * Sorts the specified range in the array using the specified {@code Comparator}. 1993 * All elements must be comparable to each other without a 1994 * {@code ClassCastException} being thrown. 1995 * 1996 * @param start 1997 * the start index to sort. 1998 * @param end 1999 * the last + 1 index to sort. 2000 * @param comparator 2001 * the {@code Comparator}. 2002 * @throws ClassCastException 2003 * if elements in the array cannot be compared to each other 2004 * using the given {@code Comparator}. 2005 * @throws IllegalArgumentException 2006 * if {@code start > end}. 2007 * @throws ArrayIndexOutOfBoundsException 2008 * if {@code start < 0} or {@code end > array.length}. 2009 */ 2010 public static <T> void sort(T[] array, int start, int end, Comparator<? super T> comparator) { 2011 TimSort.sort(array, start, end, comparator); 2012 } 2013 2014 /** 2015 * Sorts the specified array using the specified {@code Comparator}. All elements 2016 * must be comparable to each other without a {@code ClassCastException} being thrown. 2017 * 2018 * @throws ClassCastException 2019 * if elements in the array cannot be compared to each other 2020 * using the {@code Comparator}. 2021 */ 2022 public static <T> void sort(T[] array, Comparator<? super T> comparator) { 2023 TimSort.sort(array, comparator); 2024 } 2025 2026 /** 2027 * Creates a {@code String} representation of the {@code boolean[]} passed. 2028 * The result is surrounded by brackets ({@code "[]"}), each 2029 * element is converted to a {@code String} via the 2030 * {@link String#valueOf(boolean)} and separated by {@code ", "}. 2031 * If the array is {@code null}, then {@code "null"} is returned. 2032 * 2033 * @param array 2034 * the {@code boolean} array to convert. 2035 * @return the {@code String} representation of {@code array}. 2036 * @since 1.5 2037 */ 2038 public static String toString(boolean[] array) { 2039 if (array == null) { 2040 return "null"; 2041 } 2042 if (array.length == 0) { 2043 return "[]"; 2044 } 2045 StringBuilder sb = new StringBuilder(array.length * 7); 2046 sb.append('['); 2047 sb.append(array[0]); 2048 for (int i = 1; i < array.length; i++) { 2049 sb.append(", "); 2050 sb.append(array[i]); 2051 } 2052 sb.append(']'); 2053 return sb.toString(); 2054 } 2055 2056 /** 2057 * Creates a {@code String} representation of the {@code byte[]} passed. The 2058 * result is surrounded by brackets ({@code "[]"}), each element 2059 * is converted to a {@code String} via the {@link String#valueOf(int)} and 2060 * separated by {@code ", "}. If the array is {@code null}, then 2061 * {@code "null"} is returned. 2062 * 2063 * @param array 2064 * the {@code byte} array to convert. 2065 * @return the {@code String} representation of {@code array}. 2066 * @since 1.5 2067 */ 2068 public static String toString(byte[] array) { 2069 if (array == null) { 2070 return "null"; 2071 } 2072 if (array.length == 0) { 2073 return "[]"; 2074 } 2075 StringBuilder sb = new StringBuilder(array.length * 6); 2076 sb.append('['); 2077 sb.append(array[0]); 2078 for (int i = 1; i < array.length; i++) { 2079 sb.append(", "); 2080 sb.append(array[i]); 2081 } 2082 sb.append(']'); 2083 return sb.toString(); 2084 } 2085 2086 /** 2087 * Creates a {@code String} representation of the {@code char[]} passed. The 2088 * result is surrounded by brackets ({@code "[]"}), each element 2089 * is converted to a {@code String} via the {@link String#valueOf(char)} and 2090 * separated by {@code ", "}. If the array is {@code null}, then 2091 * {@code "null"} is returned. 2092 * 2093 * @param array 2094 * the {@code char} array to convert. 2095 * @return the {@code String} representation of {@code array}. 2096 * @since 1.5 2097 */ 2098 public static String toString(char[] array) { 2099 if (array == null) { 2100 return "null"; 2101 } 2102 if (array.length == 0) { 2103 return "[]"; 2104 } 2105 StringBuilder sb = new StringBuilder(array.length * 3); 2106 sb.append('['); 2107 sb.append(array[0]); 2108 for (int i = 1; i < array.length; i++) { 2109 sb.append(", "); 2110 sb.append(array[i]); 2111 } 2112 sb.append(']'); 2113 return sb.toString(); 2114 } 2115 2116 /** 2117 * Creates a {@code String} representation of the {@code double[]} passed. 2118 * The result is surrounded by brackets ({@code "[]"}), each 2119 * element is converted to a {@code String} via the 2120 * {@link String#valueOf(double)} and separated by {@code ", "}. 2121 * If the array is {@code null}, then {@code "null"} is returned. 2122 * 2123 * @param array 2124 * the {@code double} array to convert. 2125 * @return the {@code String} representation of {@code array}. 2126 * @since 1.5 2127 */ 2128 public static String toString(double[] array) { 2129 if (array == null) { 2130 return "null"; 2131 } 2132 if (array.length == 0) { 2133 return "[]"; 2134 } 2135 StringBuilder sb = new StringBuilder(array.length * 7); 2136 sb.append('['); 2137 sb.append(array[0]); 2138 for (int i = 1; i < array.length; i++) { 2139 sb.append(", "); 2140 sb.append(array[i]); 2141 } 2142 sb.append(']'); 2143 return sb.toString(); 2144 } 2145 2146 /** 2147 * Creates a {@code String} representation of the {@code float[]} passed. 2148 * The result is surrounded by brackets ({@code "[]"}), each 2149 * element is converted to a {@code String} via the 2150 * {@link String#valueOf(float)} and separated by {@code ", "}. 2151 * If the array is {@code null}, then {@code "null"} is returned. 2152 * 2153 * @param array 2154 * the {@code float} array to convert. 2155 * @return the {@code String} representation of {@code array}. 2156 * @since 1.5 2157 */ 2158 public static String toString(float[] array) { 2159 if (array == null) { 2160 return "null"; 2161 } 2162 if (array.length == 0) { 2163 return "[]"; 2164 } 2165 StringBuilder sb = new StringBuilder(array.length * 7); 2166 sb.append('['); 2167 sb.append(array[0]); 2168 for (int i = 1; i < array.length; i++) { 2169 sb.append(", "); 2170 sb.append(array[i]); 2171 } 2172 sb.append(']'); 2173 return sb.toString(); 2174 } 2175 2176 /** 2177 * Creates a {@code String} representation of the {@code int[]} passed. The 2178 * result is surrounded by brackets ({@code "[]"}), each element 2179 * is converted to a {@code String} via the {@link String#valueOf(int)} and 2180 * separated by {@code ", "}. If the array is {@code null}, then 2181 * {@code "null"} is returned. 2182 * 2183 * @param array 2184 * the {@code int} array to convert. 2185 * @return the {@code String} representation of {@code array}. 2186 * @since 1.5 2187 */ 2188 public static String toString(int[] array) { 2189 if (array == null) { 2190 return "null"; 2191 } 2192 if (array.length == 0) { 2193 return "[]"; 2194 } 2195 StringBuilder sb = new StringBuilder(array.length * 6); 2196 sb.append('['); 2197 sb.append(array[0]); 2198 for (int i = 1; i < array.length; i++) { 2199 sb.append(", "); 2200 sb.append(array[i]); 2201 } 2202 sb.append(']'); 2203 return sb.toString(); 2204 } 2205 2206 /** 2207 * Creates a {@code String} representation of the {@code long[]} passed. The 2208 * result is surrounded by brackets ({@code "[]"}), each element 2209 * is converted to a {@code String} via the {@link String#valueOf(long)} and 2210 * separated by {@code ", "}. If the array is {@code null}, then 2211 * {@code "null"} is returned. 2212 * 2213 * @param array 2214 * the {@code long} array to convert. 2215 * @return the {@code String} representation of {@code array}. 2216 * @since 1.5 2217 */ 2218 public static String toString(long[] array) { 2219 if (array == null) { 2220 return "null"; 2221 } 2222 if (array.length == 0) { 2223 return "[]"; 2224 } 2225 StringBuilder sb = new StringBuilder(array.length * 6); 2226 sb.append('['); 2227 sb.append(array[0]); 2228 for (int i = 1; i < array.length; i++) { 2229 sb.append(", "); 2230 sb.append(array[i]); 2231 } 2232 sb.append(']'); 2233 return sb.toString(); 2234 } 2235 2236 /** 2237 * Creates a {@code String} representation of the {@code short[]} passed. 2238 * The result is surrounded by brackets ({@code "[]"}), each 2239 * element is converted to a {@code String} via the 2240 * {@link String#valueOf(int)} and separated by {@code ", "}. If 2241 * the array is {@code null}, then {@code "null"} is returned. 2242 * 2243 * @param array 2244 * the {@code short} array to convert. 2245 * @return the {@code String} representation of {@code array}. 2246 * @since 1.5 2247 */ 2248 public static String toString(short[] array) { 2249 if (array == null) { 2250 return "null"; 2251 } 2252 if (array.length == 0) { 2253 return "[]"; 2254 } 2255 StringBuilder sb = new StringBuilder(array.length * 6); 2256 sb.append('['); 2257 sb.append(array[0]); 2258 for (int i = 1; i < array.length; i++) { 2259 sb.append(", "); 2260 sb.append(array[i]); 2261 } 2262 sb.append(']'); 2263 return sb.toString(); 2264 } 2265 2266 /** 2267 * Creates a {@code String} representation of the {@code Object[]} passed. 2268 * The result is surrounded by brackets ({@code "[]"}), each 2269 * element is converted to a {@code String} via the 2270 * {@link String#valueOf(Object)} and separated by {@code ", "}. 2271 * If the array is {@code null}, then {@code "null"} is returned. 2272 * 2273 * @param array 2274 * the {@code Object} array to convert. 2275 * @return the {@code String} representation of {@code array}. 2276 * @since 1.5 2277 */ 2278 public static String toString(Object[] array) { 2279 if (array == null) { 2280 return "null"; 2281 } 2282 if (array.length == 0) { 2283 return "[]"; 2284 } 2285 StringBuilder sb = new StringBuilder(array.length * 7); 2286 sb.append('['); 2287 sb.append(array[0]); 2288 for (int i = 1; i < array.length; i++) { 2289 sb.append(", "); 2290 sb.append(array[i]); 2291 } 2292 sb.append(']'); 2293 return sb.toString(); 2294 } 2295 2296 /** 2297 * Creates a <i>"deep"</i> {@code String} representation of the 2298 * {@code Object[]} passed, such that if the array contains other arrays, 2299 * the {@code String} representation of those arrays is generated as well. 2300 * <p> 2301 * If any of the elements are primitive arrays, the generation is delegated 2302 * to the other {@code toString} methods in this class. If any element 2303 * contains a reference to the original array, then it will be represented 2304 * as {@code "[...]"}. If an element is an {@code Object[]}, then its 2305 * representation is generated by a recursive call to this method. All other 2306 * elements are converted via the {@link String#valueOf(Object)} method. 2307 * 2308 * @param array 2309 * the {@code Object} array to convert. 2310 * @return the {@code String} representation of {@code array}. 2311 * @since 1.5 2312 */ 2313 public static String deepToString(Object[] array) { 2314 // Special case null to prevent NPE 2315 if (array == null) { 2316 return "null"; 2317 } 2318 // delegate this to the recursive method 2319 StringBuilder buf = new StringBuilder(array.length * 9); 2320 deepToStringImpl(array, new Object[] { array }, buf); 2321 return buf.toString(); 2322 } 2323 2324 /** 2325 * Implementation method used by {@link #deepToString(Object[])}. 2326 * 2327 * @param array 2328 * the {@code Object[]} to dive into. 2329 * @param origArrays 2330 * the original {@code Object[]}; used to test for self 2331 * references. 2332 * @param sb 2333 * the {@code StringBuilder} instance to append to or 2334 * {@code null} one hasn't been created yet. 2335 * @return the result. 2336 * @see #deepToString(Object[]) 2337 */ 2338 private static void deepToStringImpl(Object[] array, Object[] origArrays, 2339 StringBuilder sb) { 2340 if (array == null) { 2341 sb.append("null"); 2342 return; 2343 } 2344 2345 sb.append('['); 2346 2347 for (int i = 0; i < array.length; i++) { 2348 if (i != 0) { 2349 sb.append(", "); 2350 } 2351 // establish current element 2352 Object elem = array[i]; 2353 if (elem == null) { 2354 // element is null 2355 sb.append("null"); 2356 } else { 2357 // get the Class of the current element 2358 Class<?> elemClass = elem.getClass(); 2359 if (elemClass.isArray()) { 2360 // element is an array type 2361 2362 // get the declared Class of the array (element) 2363 Class<?> elemElemClass = elemClass.getComponentType(); 2364 if (elemElemClass.isPrimitive()) { 2365 // element is a primitive array 2366 if (boolean.class.equals(elemElemClass)) { 2367 sb.append(toString((boolean[]) elem)); 2368 } else if (byte.class.equals(elemElemClass)) { 2369 sb.append(toString((byte[]) elem)); 2370 } else if (char.class.equals(elemElemClass)) { 2371 sb.append(toString((char[]) elem)); 2372 } else if (double.class.equals(elemElemClass)) { 2373 sb.append(toString((double[]) elem)); 2374 } else if (float.class.equals(elemElemClass)) { 2375 sb.append(toString((float[]) elem)); 2376 } else if (int.class.equals(elemElemClass)) { 2377 sb.append(toString((int[]) elem)); 2378 } else if (long.class.equals(elemElemClass)) { 2379 sb.append(toString((long[]) elem)); 2380 } else if (short.class.equals(elemElemClass)) { 2381 sb.append(toString((short[]) elem)); 2382 } else { 2383 // no other possible primitives, so we assert that 2384 throw new AssertionError(); 2385 } 2386 } else { 2387 // element is an Object[], so we assert that 2388 // assert elem instanceof Object[]; 2389 if (deepToStringImplContains(origArrays, elem)) { 2390 sb.append("[...]"); 2391 } else { 2392 Object[] newArray = (Object[]) elem; 2393 Object[] newOrigArrays = new Object[origArrays.length + 1]; 2394 System.arraycopy(origArrays, 0, newOrigArrays, 0, 2395 origArrays.length); 2396 newOrigArrays[origArrays.length] = newArray; 2397 // make the recursive call to this method 2398 deepToStringImpl(newArray, newOrigArrays, sb); 2399 } 2400 } 2401 } else { // element is NOT an array, just an Object 2402 sb.append(array[i]); 2403 } 2404 } 2405 } 2406 sb.append(']'); 2407 } 2408 2409 /** 2410 * Utility method used to assist the implementation of 2411 * {@link #deepToString(Object[])}. 2412 * 2413 * @param origArrays 2414 * An array of Object[] references. 2415 * @param array 2416 * An Object[] reference to look for in {@code origArrays}. 2417 * @return A value of {@code true} if {@code array} is an 2418 * element in {@code origArrays}. 2419 */ 2420 private static boolean deepToStringImplContains(Object[] origArrays, 2421 Object array) { 2422 if (origArrays == null || origArrays.length == 0) { 2423 return false; 2424 } 2425 for (Object element : origArrays) { 2426 if (element == array) { 2427 return true; 2428 } 2429 } 2430 return false; 2431 } 2432 2433 /** 2434 * Copies {@code newLength} elements from {@code original} into a new array. 2435 * If {@code newLength} is greater than {@code original.length}, the result is padded 2436 * with the value {@code false}. 2437 * 2438 * @param original the original array 2439 * @param newLength the length of the new array 2440 * @return the new array 2441 * @throws NegativeArraySizeException if {@code newLength < 0} 2442 * @throws NullPointerException if {@code original == null} 2443 * @since 1.6 2444 */ 2445 public static boolean[] copyOf(boolean[] original, int newLength) { 2446 if (newLength < 0) { 2447 throw new NegativeArraySizeException(Integer.toString(newLength)); 2448 } 2449 return copyOfRange(original, 0, newLength); 2450 } 2451 2452 /** 2453 * Copies {@code newLength} elements from {@code original} into a new array. 2454 * If {@code newLength} is greater than {@code original.length}, the result is padded 2455 * with the value {@code (byte) 0}. 2456 * 2457 * @param original the original array 2458 * @param newLength the length of the new array 2459 * @return the new array 2460 * @throws NegativeArraySizeException if {@code newLength < 0} 2461 * @throws NullPointerException if {@code original == null} 2462 * @since 1.6 2463 */ 2464 public static byte[] copyOf(byte[] original, int newLength) { 2465 if (newLength < 0) { 2466 throw new NegativeArraySizeException(Integer.toString(newLength)); 2467 } 2468 return copyOfRange(original, 0, newLength); 2469 } 2470 2471 /** 2472 * Copies {@code newLength} elements from {@code original} into a new array. 2473 * If {@code newLength} is greater than {@code original.length}, the result is padded 2474 * with the value {@code '\\u0000'}. 2475 * 2476 * @param original the original array 2477 * @param newLength the length of the new array 2478 * @return the new array 2479 * @throws NegativeArraySizeException if {@code newLength < 0} 2480 * @throws NullPointerException if {@code original == null} 2481 * @since 1.6 2482 */ 2483 public static char[] copyOf(char[] original, int newLength) { 2484 if (newLength < 0) { 2485 throw new NegativeArraySizeException(Integer.toString(newLength)); 2486 } 2487 return copyOfRange(original, 0, newLength); 2488 } 2489 2490 /** 2491 * Copies {@code newLength} elements from {@code original} into a new array. 2492 * If {@code newLength} is greater than {@code original.length}, the result is padded 2493 * with the value {@code 0.0d}. 2494 * 2495 * @param original the original array 2496 * @param newLength the length of the new array 2497 * @return the new array 2498 * @throws NegativeArraySizeException if {@code newLength < 0} 2499 * @throws NullPointerException if {@code original == null} 2500 * @since 1.6 2501 */ 2502 public static double[] copyOf(double[] original, int newLength) { 2503 if (newLength < 0) { 2504 throw new NegativeArraySizeException(Integer.toString(newLength)); 2505 } 2506 return copyOfRange(original, 0, newLength); 2507 } 2508 2509 /** 2510 * Copies {@code newLength} elements from {@code original} into a new array. 2511 * If {@code newLength} is greater than {@code original.length}, the result is padded 2512 * with the value {@code 0.0f}. 2513 * 2514 * @param original the original array 2515 * @param newLength the length of the new array 2516 * @return the new array 2517 * @throws NegativeArraySizeException if {@code newLength < 0} 2518 * @throws NullPointerException if {@code original == null} 2519 * @since 1.6 2520 */ 2521 public static float[] copyOf(float[] original, int newLength) { 2522 if (newLength < 0) { 2523 throw new NegativeArraySizeException(Integer.toString(newLength)); 2524 } 2525 return copyOfRange(original, 0, newLength); 2526 } 2527 2528 /** 2529 * Copies {@code newLength} elements from {@code original} into a new array. 2530 * If {@code newLength} is greater than {@code original.length}, the result is padded 2531 * with the value {@code 0}. 2532 * 2533 * @param original the original array 2534 * @param newLength the length of the new array 2535 * @return the new array 2536 * @throws NegativeArraySizeException if {@code newLength < 0} 2537 * @throws NullPointerException if {@code original == null} 2538 * @since 1.6 2539 */ 2540 public static int[] copyOf(int[] original, int newLength) { 2541 if (newLength < 0) { 2542 throw new NegativeArraySizeException(Integer.toString(newLength)); 2543 } 2544 return copyOfRange(original, 0, newLength); 2545 } 2546 2547 /** 2548 * Copies {@code newLength} elements from {@code original} into a new array. 2549 * If {@code newLength} is greater than {@code original.length}, the result is padded 2550 * with the value {@code 0L}. 2551 * 2552 * @param original the original array 2553 * @param newLength the length of the new array 2554 * @return the new array 2555 * @throws NegativeArraySizeException if {@code newLength < 0} 2556 * @throws NullPointerException if {@code original == null} 2557 * @since 1.6 2558 */ 2559 public static long[] copyOf(long[] original, int newLength) { 2560 if (newLength < 0) { 2561 throw new NegativeArraySizeException(Integer.toString(newLength)); 2562 } 2563 return copyOfRange(original, 0, newLength); 2564 } 2565 2566 /** 2567 * Copies {@code newLength} elements from {@code original} into a new array. 2568 * If {@code newLength} is greater than {@code original.length}, the result is padded 2569 * with the value {@code (short) 0}. 2570 * 2571 * @param original the original array 2572 * @param newLength the length of the new array 2573 * @return the new array 2574 * @throws NegativeArraySizeException if {@code newLength < 0} 2575 * @throws NullPointerException if {@code original == null} 2576 * @since 1.6 2577 */ 2578 public static short[] copyOf(short[] original, int newLength) { 2579 if (newLength < 0) { 2580 throw new NegativeArraySizeException(Integer.toString(newLength)); 2581 } 2582 return copyOfRange(original, 0, newLength); 2583 } 2584 2585 /** 2586 * Copies {@code newLength} elements from {@code original} into a new array. 2587 * If {@code newLength} is greater than {@code original.length}, the result is padded 2588 * with the value {@code null}. 2589 * 2590 * @param original the original array 2591 * @param newLength the length of the new array 2592 * @return the new array 2593 * @throws NegativeArraySizeException if {@code newLength < 0} 2594 * @throws NullPointerException if {@code original == null} 2595 * @since 1.6 2596 */ 2597 public static <T> T[] copyOf(T[] original, int newLength) { 2598 if (original == null) { 2599 throw new NullPointerException("original == null"); 2600 } 2601 if (newLength < 0) { 2602 throw new NegativeArraySizeException(Integer.toString(newLength)); 2603 } 2604 return copyOfRange(original, 0, newLength); 2605 } 2606 2607 /** 2608 * Copies {@code newLength} elements from {@code original} into a new array. 2609 * If {@code newLength} is greater than {@code original.length}, the result is padded 2610 * with the value {@code null}. 2611 * 2612 * @param original the original array 2613 * @param newLength the length of the new array 2614 * @param newType the class of the new array 2615 * @return the new array 2616 * @throws NegativeArraySizeException if {@code newLength < 0} 2617 * @throws NullPointerException if {@code original == null} 2618 * @throws ArrayStoreException if a value in {@code original} is incompatible with T 2619 * @since 1.6 2620 */ 2621 public static <T, U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { 2622 // We use the null pointer check in copyOfRange for exception priority compatibility. 2623 if (newLength < 0) { 2624 throw new NegativeArraySizeException(Integer.toString(newLength)); 2625 } 2626 return copyOfRange(original, 0, newLength, newType); 2627 } 2628 2629 /** 2630 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2631 * end (exclusive). The original order of elements is preserved. 2632 * If {@code end} is greater than {@code original.length}, the result is padded 2633 * with the value {@code false}. 2634 * 2635 * @param original the original array 2636 * @param start the start index, inclusive 2637 * @param end the end index, exclusive 2638 * @return the new array 2639 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2640 * @throws IllegalArgumentException if {@code start > end} 2641 * @throws NullPointerException if {@code original == null} 2642 * @since 1.6 2643 */ 2644 public static boolean[] copyOfRange(boolean[] original, int start, int end) { 2645 if (start > end) { 2646 throw new IllegalArgumentException(); 2647 } 2648 int originalLength = original.length; 2649 if (start < 0 || start > originalLength) { 2650 throw new ArrayIndexOutOfBoundsException(); 2651 } 2652 int resultLength = end - start; 2653 int copyLength = Math.min(resultLength, originalLength - start); 2654 boolean[] result = new boolean[resultLength]; 2655 System.arraycopy(original, start, result, 0, copyLength); 2656 return result; 2657 } 2658 2659 /** 2660 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2661 * end (exclusive). The original order of elements is preserved. 2662 * If {@code end} is greater than {@code original.length}, the result is padded 2663 * with the value {@code (byte) 0}. 2664 * 2665 * @param original the original array 2666 * @param start the start index, inclusive 2667 * @param end the end index, exclusive 2668 * @return the new array 2669 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2670 * @throws IllegalArgumentException if {@code start > end} 2671 * @throws NullPointerException if {@code original == null} 2672 * @since 1.6 2673 */ 2674 public static byte[] copyOfRange(byte[] original, int start, int end) { 2675 if (start > end) { 2676 throw new IllegalArgumentException(); 2677 } 2678 int originalLength = original.length; 2679 if (start < 0 || start > originalLength) { 2680 throw new ArrayIndexOutOfBoundsException(); 2681 } 2682 int resultLength = end - start; 2683 int copyLength = Math.min(resultLength, originalLength - start); 2684 byte[] result = new byte[resultLength]; 2685 System.arraycopy(original, start, result, 0, copyLength); 2686 return result; 2687 } 2688 2689 /** 2690 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2691 * end (exclusive). The original order of elements is preserved. 2692 * If {@code end} is greater than {@code original.length}, the result is padded 2693 * with the value {@code '\\u0000'}. 2694 * 2695 * @param original the original array 2696 * @param start the start index, inclusive 2697 * @param end the end index, exclusive 2698 * @return the new array 2699 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2700 * @throws IllegalArgumentException if {@code start > end} 2701 * @throws NullPointerException if {@code original == null} 2702 * @since 1.6 2703 */ 2704 public static char[] copyOfRange(char[] original, int start, int end) { 2705 if (start > end) { 2706 throw new IllegalArgumentException(); 2707 } 2708 int originalLength = original.length; 2709 if (start < 0 || start > originalLength) { 2710 throw new ArrayIndexOutOfBoundsException(); 2711 } 2712 int resultLength = end - start; 2713 int copyLength = Math.min(resultLength, originalLength - start); 2714 char[] result = new char[resultLength]; 2715 System.arraycopy(original, start, result, 0, copyLength); 2716 return result; 2717 } 2718 2719 /** 2720 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2721 * end (exclusive). The original order of elements is preserved. 2722 * If {@code end} is greater than {@code original.length}, the result is padded 2723 * with the value {@code 0.0d}. 2724 * 2725 * @param original the original array 2726 * @param start the start index, inclusive 2727 * @param end the end index, exclusive 2728 * @return the new array 2729 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2730 * @throws IllegalArgumentException if {@code start > end} 2731 * @throws NullPointerException if {@code original == null} 2732 * @since 1.6 2733 */ 2734 public static double[] copyOfRange(double[] original, int start, int end) { 2735 if (start > end) { 2736 throw new IllegalArgumentException(); 2737 } 2738 int originalLength = original.length; 2739 if (start < 0 || start > originalLength) { 2740 throw new ArrayIndexOutOfBoundsException(); 2741 } 2742 int resultLength = end - start; 2743 int copyLength = Math.min(resultLength, originalLength - start); 2744 double[] result = new double[resultLength]; 2745 System.arraycopy(original, start, result, 0, copyLength); 2746 return result; 2747 } 2748 2749 /** 2750 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2751 * end (exclusive). The original order of elements is preserved. 2752 * If {@code end} is greater than {@code original.length}, the result is padded 2753 * with the value {@code 0.0f}. 2754 * 2755 * @param original the original array 2756 * @param start the start index, inclusive 2757 * @param end the end index, exclusive 2758 * @return the new array 2759 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2760 * @throws IllegalArgumentException if {@code start > end} 2761 * @throws NullPointerException if {@code original == null} 2762 * @since 1.6 2763 */ 2764 public static float[] copyOfRange(float[] original, int start, int end) { 2765 if (start > end) { 2766 throw new IllegalArgumentException(); 2767 } 2768 int originalLength = original.length; 2769 if (start < 0 || start > originalLength) { 2770 throw new ArrayIndexOutOfBoundsException(); 2771 } 2772 int resultLength = end - start; 2773 int copyLength = Math.min(resultLength, originalLength - start); 2774 float[] result = new float[resultLength]; 2775 System.arraycopy(original, start, result, 0, copyLength); 2776 return result; 2777 } 2778 2779 /** 2780 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2781 * end (exclusive). The original order of elements is preserved. 2782 * If {@code end} is greater than {@code original.length}, the result is padded 2783 * with the value {@code 0}. 2784 * 2785 * @param original the original array 2786 * @param start the start index, inclusive 2787 * @param end the end index, exclusive 2788 * @return the new array 2789 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2790 * @throws IllegalArgumentException if {@code start > end} 2791 * @throws NullPointerException if {@code original == null} 2792 * @since 1.6 2793 */ 2794 public static int[] copyOfRange(int[] original, int start, int end) { 2795 if (start > end) { 2796 throw new IllegalArgumentException(); 2797 } 2798 int originalLength = original.length; 2799 if (start < 0 || start > originalLength) { 2800 throw new ArrayIndexOutOfBoundsException(); 2801 } 2802 int resultLength = end - start; 2803 int copyLength = Math.min(resultLength, originalLength - start); 2804 int[] result = new int[resultLength]; 2805 System.arraycopy(original, start, result, 0, copyLength); 2806 return result; 2807 } 2808 2809 /** 2810 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2811 * end (exclusive). The original order of elements is preserved. 2812 * If {@code end} is greater than {@code original.length}, the result is padded 2813 * with the value {@code 0L}. 2814 * 2815 * @param original the original array 2816 * @param start the start index, inclusive 2817 * @param end the end index, exclusive 2818 * @return the new array 2819 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2820 * @throws IllegalArgumentException if {@code start > end} 2821 * @throws NullPointerException if {@code original == null} 2822 * @since 1.6 2823 */ 2824 public static long[] copyOfRange(long[] original, int start, int end) { 2825 if (start > end) { 2826 throw new IllegalArgumentException(); 2827 } 2828 int originalLength = original.length; 2829 if (start < 0 || start > originalLength) { 2830 throw new ArrayIndexOutOfBoundsException(); 2831 } 2832 int resultLength = end - start; 2833 int copyLength = Math.min(resultLength, originalLength - start); 2834 long[] result = new long[resultLength]; 2835 System.arraycopy(original, start, result, 0, copyLength); 2836 return result; 2837 } 2838 2839 /** 2840 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2841 * end (exclusive). The original order of elements is preserved. 2842 * If {@code end} is greater than {@code original.length}, the result is padded 2843 * with the value {@code (short) 0}. 2844 * 2845 * @param original the original array 2846 * @param start the start index, inclusive 2847 * @param end the end index, exclusive 2848 * @return the new array 2849 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2850 * @throws IllegalArgumentException if {@code start > end} 2851 * @throws NullPointerException if {@code original == null} 2852 * @since 1.6 2853 */ 2854 public static short[] copyOfRange(short[] original, int start, int end) { 2855 if (start > end) { 2856 throw new IllegalArgumentException(); 2857 } 2858 int originalLength = original.length; 2859 if (start < 0 || start > originalLength) { 2860 throw new ArrayIndexOutOfBoundsException(); 2861 } 2862 int resultLength = end - start; 2863 int copyLength = Math.min(resultLength, originalLength - start); 2864 short[] result = new short[resultLength]; 2865 System.arraycopy(original, start, result, 0, copyLength); 2866 return result; 2867 } 2868 2869 /** 2870 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2871 * end (exclusive). The original order of elements is preserved. 2872 * If {@code end} is greater than {@code original.length}, the result is padded 2873 * with the value {@code null}. 2874 * 2875 * @param original the original array 2876 * @param start the start index, inclusive 2877 * @param end the end index, exclusive 2878 * @return the new array 2879 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2880 * @throws IllegalArgumentException if {@code start > end} 2881 * @throws NullPointerException if {@code original == null} 2882 * @since 1.6 2883 */ 2884 @SuppressWarnings("unchecked") 2885 public static <T> T[] copyOfRange(T[] original, int start, int end) { 2886 int originalLength = original.length; // For exception priority compatibility. 2887 if (start > end) { 2888 throw new IllegalArgumentException(); 2889 } 2890 if (start < 0 || start > originalLength) { 2891 throw new ArrayIndexOutOfBoundsException(); 2892 } 2893 int resultLength = end - start; 2894 int copyLength = Math.min(resultLength, originalLength - start); 2895 T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), resultLength); 2896 System.arraycopy(original, start, result, 0, copyLength); 2897 return result; 2898 } 2899 2900 /** 2901 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2902 * end (exclusive). The original order of elements is preserved. 2903 * If {@code end} is greater than {@code original.length}, the result is padded 2904 * with the value {@code null}. 2905 * 2906 * @param original the original array 2907 * @param start the start index, inclusive 2908 * @param end the end index, exclusive 2909 * @return the new array 2910 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2911 * @throws IllegalArgumentException if {@code start > end} 2912 * @throws NullPointerException if {@code original == null} 2913 * @throws ArrayStoreException if a value in {@code original} is incompatible with T 2914 * @since 1.6 2915 */ 2916 @SuppressWarnings("unchecked") 2917 public static <T, U> T[] copyOfRange(U[] original, int start, int end, Class<? extends T[]> newType) { 2918 if (start > end) { 2919 throw new IllegalArgumentException(); 2920 } 2921 int originalLength = original.length; 2922 if (start < 0 || start > originalLength) { 2923 throw new ArrayIndexOutOfBoundsException(); 2924 } 2925 int resultLength = end - start; 2926 int copyLength = Math.min(resultLength, originalLength - start); 2927 T[] result = (T[]) Array.newInstance(newType.getComponentType(), resultLength); 2928 System.arraycopy(original, start, result, 0, copyLength); 2929 return result; 2930 } 2931} 2932