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 18 package java.util; 19 20 import java.io.Serializable; 21 import java.lang.reflect.Array; 22 23 /** 24 * {@code Arrays} contains static methods which operate on arrays. 25 * 26 * @since 1.2 27 */ 28 public 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 ArrayList(E[] storage)36 ArrayList(E[] storage) { 37 if (storage == null) { 38 throw new NullPointerException("storage == null"); 39 } 40 a = storage; 41 } 42 43 @Override contains(Object object)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 get(int location)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 indexOf(Object object)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 lastIndexOf(Object object)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 set(int location, E object)107 public E set(int location, E object) { 108 E result = a[location]; 109 a[location] = object; 110 return result; 111 } 112 113 @Override size()114 public int size() { 115 return a.length; 116 } 117 118 @Override toArray()119 public Object[] toArray() { 120 return a.clone(); 121 } 122 123 @Override 124 @SuppressWarnings({"unchecked", "SuspiciousSystemArraycopy"}) toArray(T[] contents)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 Arrays()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 asList(T... array)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 */ binarySearch(byte[] array, byte value)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 */ binarySearch(byte[] array, int startIndex, int endIndex, byte value)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 */ binarySearch(char[] array, char value)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 */ binarySearch(char[] array, int startIndex, int endIndex, char value)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 */ binarySearch(double[] array, double value)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 */ binarySearch(double[] array, int startIndex, int endIndex, double value)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 */ binarySearch(float[] array, float value)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 */ binarySearch(float[] array, int startIndex, int endIndex, float value)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 */ binarySearch(int[] array, int value)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 */ binarySearch(int[] array, int startIndex, int endIndex, int value)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 */ binarySearch(long[] array, long value)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 */ binarySearch(long[] array, int startIndex, int endIndex, long value)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 */ binarySearch(Object[] array, Object value)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 */ binarySearch(Object[] array, int startIndex, int endIndex, Object value)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 */ binarySearch(T[] array, T value, Comparator<? super T> comparator)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 */ binarySearch(T[] array, int startIndex, int endIndex, T value, Comparator<? super T> comparator)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 */ binarySearch(short[] array, short value)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 */ binarySearch(short[] array, int startIndex, int endIndex, short value)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 checkBinarySearchBounds(int startIndex, int endIndex, int length)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 */ fill(byte[] array, byte value)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 */ fill(byte[] array, int start, int end, byte value)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 */ fill(short[] array, short value)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 */ fill(short[] array, int start, int end, short value)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 */ fill(char[] array, char value)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 */ fill(char[] array, int start, int end, char value)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 */ fill(int[] array, int value)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 */ fill(int[] array, int start, int end, int value)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 */ fill(long[] array, long value)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 */ fill(long[] array, int start, int end, long value)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 */ fill(float[] array, float value)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 */ fill(float[] array, int start, int end, float value)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 */ fill(double[] array, double value)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 */ fill(double[] array, int start, int end, double value)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 */ fill(boolean[] array, boolean value)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 */ fill(boolean[] array, int start, int end, boolean value)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 */ fill(Object[] array, Object value)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 */ fill(Object[] array, int start, int end, Object value)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 */ hashCode(boolean[] array)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 */ hashCode(int[] array)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 */ hashCode(short[] array)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 */ hashCode(char[] array)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 */ hashCode(byte[] array)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 */ hashCode(long[] array)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 */ hashCode(float[] array)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 */ hashCode(double[] array)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 */ hashCode(Object[] array)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 */ deepHashCode(Object[] array)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 deepHashCodeElement(Object element)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 (element instanceof Object[]) { 1323 return deepHashCode((Object[]) element); 1324 } else if (cl == int.class) { 1325 return hashCode((int[]) element); 1326 } else if (cl == char.class) { 1327 return hashCode((char[]) element); 1328 } else if (cl == boolean.class) { 1329 return hashCode((boolean[]) element); 1330 } else if (cl == byte.class) { 1331 return hashCode((byte[]) element); 1332 } else if (cl == long.class) { 1333 return hashCode((long[]) element); 1334 } else if (cl == float.class) { 1335 return hashCode((float[]) element); 1336 } else if (cl == double.class) { 1337 return hashCode((double[]) element); 1338 } else { 1339 return hashCode((short[]) element); 1340 } 1341 } 1342 1343 /** 1344 * Compares the two arrays. 1345 * 1346 * @param array1 1347 * the first {@code byte} array. 1348 * @param array2 1349 * the second {@code byte} array. 1350 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1351 * same length and the elements at each index in the two arrays are 1352 * equal, {@code false} otherwise. 1353 */ equals(byte[] array1, byte[] array2)1354 public static boolean equals(byte[] array1, byte[] array2) { 1355 if (array1 == array2) { 1356 return true; 1357 } 1358 if (array1 == null || array2 == null || array1.length != array2.length) { 1359 return false; 1360 } 1361 for (int i = 0; i < array1.length; i++) { 1362 if (array1[i] != array2[i]) { 1363 return false; 1364 } 1365 } 1366 return true; 1367 } 1368 1369 /** 1370 * Compares the two arrays. 1371 * 1372 * @param array1 1373 * the first {@code short} array. 1374 * @param array2 1375 * the second {@code short} array. 1376 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1377 * same length and the elements at each index in the two arrays are 1378 * equal, {@code false} otherwise. 1379 */ equals(short[] array1, short[] array2)1380 public static boolean equals(short[] array1, short[] array2) { 1381 if (array1 == array2) { 1382 return true; 1383 } 1384 if (array1 == null || array2 == null || array1.length != array2.length) { 1385 return false; 1386 } 1387 for (int i = 0; i < array1.length; i++) { 1388 if (array1[i] != array2[i]) { 1389 return false; 1390 } 1391 } 1392 return true; 1393 } 1394 1395 /** 1396 * Compares the two arrays. 1397 * 1398 * @param array1 1399 * the first {@code char} array. 1400 * @param array2 1401 * the second {@code char} array. 1402 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1403 * same length and the elements at each index in the two arrays are 1404 * equal, {@code false} otherwise. 1405 */ equals(char[] array1, char[] array2)1406 public static boolean equals(char[] array1, char[] array2) { 1407 if (array1 == array2) { 1408 return true; 1409 } 1410 if (array1 == null || array2 == null || array1.length != array2.length) { 1411 return false; 1412 } 1413 for (int i = 0; i < array1.length; i++) { 1414 if (array1[i] != array2[i]) { 1415 return false; 1416 } 1417 } 1418 return true; 1419 } 1420 1421 /** 1422 * Compares the two arrays. 1423 * 1424 * @param array1 1425 * the first {@code int} array. 1426 * @param array2 1427 * the second {@code int} array. 1428 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1429 * same length and the elements at each index in the two arrays are 1430 * equal, {@code false} otherwise. 1431 */ equals(int[] array1, int[] array2)1432 public static boolean equals(int[] array1, int[] array2) { 1433 if (array1 == array2) { 1434 return true; 1435 } 1436 if (array1 == null || array2 == null || array1.length != array2.length) { 1437 return false; 1438 } 1439 for (int i = 0; i < array1.length; i++) { 1440 if (array1[i] != array2[i]) { 1441 return false; 1442 } 1443 } 1444 return true; 1445 } 1446 1447 /** 1448 * Compares the two arrays. 1449 * 1450 * @param array1 1451 * the first {@code long} array. 1452 * @param array2 1453 * the second {@code long} array. 1454 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1455 * same length and the elements at each index in the two arrays are 1456 * equal, {@code false} otherwise. 1457 */ equals(long[] array1, long[] array2)1458 public static boolean equals(long[] array1, long[] array2) { 1459 if (array1 == array2) { 1460 return true; 1461 } 1462 if (array1 == null || array2 == null || array1.length != array2.length) { 1463 return false; 1464 } 1465 for (int i = 0; i < array1.length; i++) { 1466 if (array1[i] != array2[i]) { 1467 return false; 1468 } 1469 } 1470 return true; 1471 } 1472 1473 /** 1474 * Compares the two arrays. The values are compared in the same manner as 1475 * {@code Float.equals()}. 1476 * 1477 * @param array1 1478 * the first {@code float} array. 1479 * @param array2 1480 * the second {@code float} array. 1481 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1482 * same length and the elements at each index in the two arrays are 1483 * equal, {@code false} otherwise. 1484 * @see Float#equals(Object) 1485 */ equals(float[] array1, float[] array2)1486 public static boolean equals(float[] array1, float[] array2) { 1487 if (array1 == array2) { 1488 return true; 1489 } 1490 if (array1 == null || array2 == null || array1.length != array2.length) { 1491 return false; 1492 } 1493 for (int i = 0; i < array1.length; i++) { 1494 if (Float.floatToIntBits(array1[i]) != Float 1495 .floatToIntBits(array2[i])) { 1496 return false; 1497 } 1498 } 1499 return true; 1500 } 1501 1502 /** 1503 * Compares the two arrays. The values are compared in the same manner as 1504 * {@code Double.equals()}. 1505 * 1506 * @param array1 1507 * the first {@code double} array. 1508 * @param array2 1509 * the second {@code double} array. 1510 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1511 * same length and the elements at each index in the two arrays are 1512 * equal, {@code false} otherwise. 1513 * @see Double#equals(Object) 1514 */ equals(double[] array1, double[] array2)1515 public static boolean equals(double[] array1, double[] array2) { 1516 if (array1 == array2) { 1517 return true; 1518 } 1519 if (array1 == null || array2 == null || array1.length != array2.length) { 1520 return false; 1521 } 1522 for (int i = 0; i < array1.length; i++) { 1523 if (Double.doubleToLongBits(array1[i]) != Double 1524 .doubleToLongBits(array2[i])) { 1525 return false; 1526 } 1527 } 1528 return true; 1529 } 1530 1531 /** 1532 * Compares the two arrays. 1533 * 1534 * @param array1 1535 * the first {@code boolean} array. 1536 * @param array2 1537 * the second {@code boolean} array. 1538 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1539 * same length and the elements at each index in the two arrays are 1540 * equal, {@code false} otherwise. 1541 */ equals(boolean[] array1, boolean[] array2)1542 public static boolean equals(boolean[] array1, boolean[] array2) { 1543 if (array1 == array2) { 1544 return true; 1545 } 1546 if (array1 == null || array2 == null || array1.length != array2.length) { 1547 return false; 1548 } 1549 for (int i = 0; i < array1.length; i++) { 1550 if (array1[i] != array2[i]) { 1551 return false; 1552 } 1553 } 1554 return true; 1555 } 1556 1557 /** 1558 * Compares the two arrays. 1559 * 1560 * @param array1 1561 * the first {@code Object} array. 1562 * @param array2 1563 * the second {@code Object} array. 1564 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1565 * same length and the elements at each index in the two arrays are 1566 * equal according to {@code equals()}, {@code false} otherwise. 1567 */ equals(Object[] array1, Object[] array2)1568 public static boolean equals(Object[] array1, Object[] array2) { 1569 if (array1 == array2) { 1570 return true; 1571 } 1572 if (array1 == null || array2 == null || array1.length != array2.length) { 1573 return false; 1574 } 1575 for (int i = 0; i < array1.length; i++) { 1576 Object e1 = array1[i], e2 = array2[i]; 1577 if (!(e1 == null ? e2 == null : e1.equals(e2))) { 1578 return false; 1579 } 1580 } 1581 return true; 1582 } 1583 1584 /** 1585 * Returns {@code true} if the two given arrays are deeply equal to one another. 1586 * Unlike the method {@code equals(Object[] array1, Object[] array2)}, this method 1587 * is appropriate for use for nested arrays of arbitrary depth. 1588 * <p> 1589 * Two array references are considered deeply equal if they are both {@code null}, 1590 * or if they refer to arrays that have the same length and the elements at 1591 * each index in the two arrays are equal. 1592 * <p> 1593 * Two {@code null} elements {@code element1} and {@code element2} are possibly deeply equal if any 1594 * of the following conditions satisfied: 1595 * <p> 1596 * {@code element1} and {@code element2} are both arrays of object reference types, and 1597 * {@code Arrays.deepEquals(element1, element2)} would return {@code true}. 1598 * <p> 1599 * {@code element1} and {@code element2} are arrays of the same primitive type, and the 1600 * appropriate overloading of {@code Arrays.equals(element1, element2)} would return 1601 * {@code true}. 1602 * <p> 1603 * {@code element1 == element2} 1604 * <p> 1605 * {@code element1.equals(element2)} would return {@code true}. 1606 * <p> 1607 * Note that this definition permits {@code null} elements at any depth. 1608 * <p> 1609 * If either of the given arrays contain themselves as elements, the 1610 * behavior of this method is uncertain. 1611 * 1612 * @param array1 1613 * the first {@code Object} array. 1614 * @param array2 1615 * the second {@code Object} array. 1616 * @return {@code true} if both arrays are {@code null} or if the arrays have the 1617 * same length and the elements at each index in the two arrays are 1618 * equal according to {@code equals()}, {@code false} otherwise. 1619 */ deepEquals(Object[] array1, Object[] array2)1620 public static boolean deepEquals(Object[] array1, Object[] array2) { 1621 if (array1 == array2) { 1622 return true; 1623 } 1624 if (array1 == null || array2 == null || array1.length != array2.length) { 1625 return false; 1626 } 1627 for (int i = 0; i < array1.length; i++) { 1628 Object e1 = array1[i], e2 = array2[i]; 1629 1630 if (!deepEqualsElements(e1, e2)) { 1631 return false; 1632 } 1633 } 1634 return true; 1635 } 1636 deepEqualsElements(Object e1, Object e2)1637 private static boolean deepEqualsElements(Object e1, Object e2) { 1638 Class<?> cl1, cl2; 1639 1640 if (e1 == e2) { 1641 return true; 1642 } 1643 1644 if (e1 == null || e2 == null) { 1645 return false; 1646 } 1647 1648 cl1 = e1.getClass().getComponentType(); 1649 cl2 = e2.getClass().getComponentType(); 1650 1651 if (cl1 != cl2) { 1652 return false; 1653 } 1654 1655 if (cl1 == null) { 1656 return e1.equals(e2); 1657 } 1658 1659 /* 1660 * compare as arrays 1661 */ 1662 if (e1 instanceof Object[]) { 1663 return deepEquals((Object[]) e1, (Object[]) e2); 1664 } else if (cl1 == int.class) { 1665 return equals((int[]) e1, (int[]) e2); 1666 } else if (cl1 == char.class) { 1667 return equals((char[]) e1, (char[]) e2); 1668 } else if (cl1 == boolean.class) { 1669 return equals((boolean[]) e1, (boolean[]) e2); 1670 } else if (cl1 == byte.class) { 1671 return equals((byte[]) e1, (byte[]) e2); 1672 } else if (cl1 == long.class) { 1673 return equals((long[]) e1, (long[]) e2); 1674 } else if (cl1 == float.class) { 1675 return equals((float[]) e1, (float[]) e2); 1676 } else if (cl1 == double.class) { 1677 return equals((double[]) e1, (double[]) e2); 1678 } else { 1679 return equals((short[]) e1, (short[]) e2); 1680 } 1681 } 1682 1683 /** 1684 * Sorts the specified array in ascending numerical order. 1685 * 1686 * @param array 1687 * the {@code byte} array to be sorted. 1688 */ sort(byte[] array)1689 public static void sort(byte[] array) { 1690 DualPivotQuicksort.sort(array); 1691 } 1692 1693 /** 1694 * Sorts the specified range in the array in ascending numerical order. 1695 * 1696 * @param array 1697 * the {@code byte} array to be sorted. 1698 * @param start 1699 * the start index to sort. 1700 * @param end 1701 * the last + 1 index to sort. 1702 * @throws IllegalArgumentException 1703 * if {@code start > end}. 1704 * @throws ArrayIndexOutOfBoundsException 1705 * if {@code start < 0} or {@code end > array.length}. 1706 */ sort(byte[] array, int start, int end)1707 public static void sort(byte[] array, int start, int end) { 1708 DualPivotQuicksort.sort(array, start, end); 1709 } 1710 1711 /** 1712 * Checks that the range described by {@code offset} and {@code count} doesn't exceed 1713 * {@code arrayLength}. 1714 * 1715 * @hide 1716 */ checkOffsetAndCount(int arrayLength, int offset, int count)1717 public static void checkOffsetAndCount(int arrayLength, int offset, int count) { 1718 if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) { 1719 throw new ArrayIndexOutOfBoundsException(arrayLength, offset, 1720 count); 1721 } 1722 } 1723 1724 /** 1725 * Checks that the range described by {@code start} and {@code end} doesn't exceed 1726 * {@code len}. 1727 * 1728 * @hide 1729 */ checkStartAndEnd(int len, int start, int end)1730 public static void checkStartAndEnd(int len, int start, int end) { 1731 if (start < 0 || end > len) { 1732 throw new ArrayIndexOutOfBoundsException("start < 0 || end > len." 1733 + " start=" + start + ", end=" + end + ", len=" + len); 1734 } 1735 if (start > end) { 1736 throw new IllegalArgumentException("start > end: " + start + " > " + end); 1737 } 1738 } 1739 1740 /** 1741 * Sorts the specified array in ascending numerical order. 1742 * 1743 * @param array 1744 * the {@code char} array to be sorted. 1745 */ sort(char[] array)1746 public static void sort(char[] array) { 1747 DualPivotQuicksort.sort(array); 1748 } 1749 1750 /** 1751 * Sorts the specified range in the array in ascending numerical order. 1752 * 1753 * @param array 1754 * the {@code char} array to be sorted. 1755 * @param start 1756 * the start index to sort. 1757 * @param end 1758 * the last + 1 index to sort. 1759 * @throws IllegalArgumentException 1760 * if {@code start > end}. 1761 * @throws ArrayIndexOutOfBoundsException 1762 * if {@code start < 0} or {@code end > array.length}. 1763 */ sort(char[] array, int start, int end)1764 public static void sort(char[] array, int start, int end) { 1765 DualPivotQuicksort.sort(array, start, end); 1766 } 1767 1768 /** 1769 * Sorts the specified array in ascending numerical order. 1770 * 1771 * @param array 1772 * the {@code double} array to be sorted. 1773 * @see #sort(double[], int, int) 1774 */ sort(double[] array)1775 public static void sort(double[] array) { 1776 DualPivotQuicksort.sort(array); 1777 } 1778 1779 /** 1780 * Sorts the specified range in the array in ascending numerical order. The 1781 * values are sorted according to the order imposed by {@code Double.compareTo()}. 1782 * 1783 * @param array 1784 * the {@code double} array to be sorted. 1785 * @param start 1786 * the start index to sort. 1787 * @param end 1788 * the last + 1 index to sort. 1789 * @throws IllegalArgumentException 1790 * if {@code start > end}. 1791 * @throws ArrayIndexOutOfBoundsException 1792 * if {@code start < 0} or {@code end > array.length}. 1793 * @see Double#compareTo(Double) 1794 */ sort(double[] array, int start, int end)1795 public static void sort(double[] array, int start, int end) { 1796 DualPivotQuicksort.sort(array, start, end); 1797 } 1798 1799 /** 1800 * Sorts the specified array in ascending numerical order. 1801 * 1802 * @param array 1803 * the {@code float} array to be sorted. 1804 * @see #sort(float[], int, int) 1805 */ sort(float[] array)1806 public static void sort(float[] array) { 1807 DualPivotQuicksort.sort(array); 1808 } 1809 1810 /** 1811 * Sorts the specified range in the array in ascending numerical order. The 1812 * values are sorted according to the order imposed by {@code Float.compareTo()}. 1813 * 1814 * @param array 1815 * the {@code float} array to be sorted. 1816 * @param start 1817 * the start index to sort. 1818 * @param end 1819 * the last + 1 index to sort. 1820 * @throws IllegalArgumentException 1821 * if {@code start > end}. 1822 * @throws ArrayIndexOutOfBoundsException 1823 * if {@code start < 0} or {@code end > array.length}. 1824 * @see Float#compareTo(Float) 1825 */ sort(float[] array, int start, int end)1826 public static void sort(float[] array, int start, int end) { 1827 DualPivotQuicksort.sort(array, start, end); 1828 } 1829 1830 /** 1831 * Sorts the specified array in ascending numerical order. 1832 * 1833 * @param array 1834 * the {@code int} array to be sorted. 1835 */ sort(int[] array)1836 public static void sort(int[] array) { 1837 DualPivotQuicksort.sort(array); 1838 } 1839 1840 /** 1841 * Sorts the specified range in the array in ascending numerical order. 1842 * 1843 * @param array 1844 * the {@code int} array to be sorted. 1845 * @param start 1846 * the start index to sort. 1847 * @param end 1848 * the last + 1 index to sort. 1849 * @throws IllegalArgumentException 1850 * if {@code start > end}. 1851 * @throws ArrayIndexOutOfBoundsException 1852 * if {@code start < 0} or {@code end > array.length}. 1853 */ sort(int[] array, int start, int end)1854 public static void sort(int[] array, int start, int end) { 1855 DualPivotQuicksort.sort(array, start, end); 1856 } 1857 1858 /** 1859 * Sorts the specified array in ascending numerical order. 1860 * 1861 * @param array 1862 * the {@code long} array to be sorted. 1863 */ sort(long[] array)1864 public static void sort(long[] array) { 1865 DualPivotQuicksort.sort(array); 1866 } 1867 1868 /** 1869 * Sorts the specified range in the array in ascending numerical order. 1870 * 1871 * @param array 1872 * the {@code long} array to be sorted. 1873 * @param start 1874 * the start index to sort. 1875 * @param end 1876 * the last + 1 index to sort. 1877 * @throws IllegalArgumentException 1878 * if {@code start > end}. 1879 * @throws ArrayIndexOutOfBoundsException 1880 * if {@code start < 0} or {@code end > array.length}. 1881 */ sort(long[] array, int start, int end)1882 public static void sort(long[] array, int start, int end) { 1883 DualPivotQuicksort.sort(array, start, end); 1884 } 1885 1886 /** 1887 * Sorts the specified array in ascending numerical order. 1888 * 1889 * @param array 1890 * the {@code short} array to be sorted. 1891 */ sort(short[] array)1892 public static void sort(short[] array) { 1893 DualPivotQuicksort.sort(array); 1894 } 1895 1896 /** 1897 * Sorts the specified range in the array in ascending numerical order. 1898 * 1899 * @param array 1900 * the {@code short} array to be sorted. 1901 * @param start 1902 * the start index to sort. 1903 * @param end 1904 * the last + 1 index to sort. 1905 * @throws IllegalArgumentException 1906 * if {@code start > end}. 1907 * @throws ArrayIndexOutOfBoundsException 1908 * if {@code start < 0} or {@code end > array.length}. 1909 */ sort(short[] array, int start, int end)1910 public static void sort(short[] array, int start, int end) { 1911 DualPivotQuicksort.sort(array, start, end); 1912 } 1913 1914 // BEGIN android-note 1915 1916 /* 1917 * <p>If this platform has an optimizing VM, check whether ComparableTimSort 1918 * offers any performance benefit over TimSort in conjunction with a 1919 * comparator that returns: 1920 * {@code ((Comparable)first).compareTo(Second)}. 1921 * If not, you are better off deleting ComparableTimSort to eliminate the 1922 * code duplication. In other words, the commented out code below 1923 * is the preferable implementation for sorting arrays of Comparables if it 1924 * offers sufficient performance. 1925 */ 1926 1927 // /** 1928 // * A comparator that implements the natural order of a group of 1929 // * mutually comparable elements. Using this comparator saves us 1930 // * from duplicating most of the code in this file (one version for 1931 // * Comparables, one for explicit comparators). 1932 // */ 1933 // private static final Comparator<Object> NATURAL_ORDER = new Comparator<Object>() { 1934 // @SuppressWarnings("unchecked") 1935 // public int compare(Object first, Object second) { 1936 // return ((Comparable<Object>)first).compareTo(second); 1937 // } 1938 // }; 1939 // 1940 // public static void sort(Object[] a) { 1941 // sort(a, 0, a.length, NATURAL_ORDER); 1942 // } 1943 // 1944 // public static void sort(Object[] a, int fromIndex, int toIndex) { 1945 // sort(a, fromIndex, toIndex, NATURAL_ORDER); 1946 // } 1947 1948 // END android-note 1949 1950 /** 1951 * Sorts the specified array in ascending natural order. 1952 * 1953 * @throws ClassCastException if any element does not implement {@code Comparable}, 1954 * or if {@code compareTo} throws for any pair of elements. 1955 */ sort(Object[] array)1956 public static void sort(Object[] array) { 1957 ComparableTimSort.sort(array); 1958 } 1959 1960 /** 1961 * Sorts the specified range in the array in ascending natural order. 1962 * 1963 * @param start 1964 * the start index to sort. 1965 * @param end 1966 * the last + 1 index to sort. 1967 * @throws ClassCastException if any element does not implement {@code Comparable}, 1968 * or if {@code compareTo} throws for any pair of elements. 1969 * @throws IllegalArgumentException 1970 * if {@code start > end}. 1971 * @throws ArrayIndexOutOfBoundsException 1972 * if {@code start < 0} or {@code end > array.length}. 1973 */ sort(Object[] array, int start, int end)1974 public static void sort(Object[] array, int start, int end) { 1975 ComparableTimSort.sort(array, start, end); 1976 } 1977 1978 /** 1979 * Sorts the specified range in the array using the specified {@code Comparator}. 1980 * All elements must be comparable to each other without a 1981 * {@code ClassCastException} being thrown. 1982 * 1983 * @param start 1984 * the start index to sort. 1985 * @param end 1986 * the last + 1 index to sort. 1987 * @param comparator 1988 * the {@code Comparator}. 1989 * @throws ClassCastException 1990 * if elements in the array cannot be compared to each other 1991 * using the given {@code Comparator}. 1992 * @throws IllegalArgumentException 1993 * if {@code start > end}. 1994 * @throws ArrayIndexOutOfBoundsException 1995 * if {@code start < 0} or {@code end > array.length}. 1996 */ sort(T[] array, int start, int end, Comparator<? super T> comparator)1997 public static <T> void sort(T[] array, int start, int end, Comparator<? super T> comparator) { 1998 TimSort.sort(array, start, end, comparator); 1999 } 2000 2001 /** 2002 * Sorts the specified array using the specified {@code Comparator}. All elements 2003 * must be comparable to each other without a {@code ClassCastException} being thrown. 2004 * 2005 * @throws ClassCastException 2006 * if elements in the array cannot be compared to each other 2007 * using the {@code Comparator}. 2008 */ sort(T[] array, Comparator<? super T> comparator)2009 public static <T> void sort(T[] array, Comparator<? super T> comparator) { 2010 TimSort.sort(array, comparator); 2011 } 2012 2013 /** 2014 * Creates a {@code String} representation of the {@code boolean[]} passed. 2015 * The result is surrounded by brackets ({@code "[]"}), each 2016 * element is converted to a {@code String} via the 2017 * {@link String#valueOf(boolean)} and separated by {@code ", "}. 2018 * If the array is {@code null}, then {@code "null"} is returned. 2019 * 2020 * @param array 2021 * the {@code boolean} array to convert. 2022 * @return the {@code String} representation of {@code array}. 2023 * @since 1.5 2024 */ toString(boolean[] array)2025 public static String toString(boolean[] array) { 2026 if (array == null) { 2027 return "null"; 2028 } 2029 if (array.length == 0) { 2030 return "[]"; 2031 } 2032 StringBuilder sb = new StringBuilder(array.length * 7); 2033 sb.append('['); 2034 sb.append(array[0]); 2035 for (int i = 1; i < array.length; i++) { 2036 sb.append(", "); 2037 sb.append(array[i]); 2038 } 2039 sb.append(']'); 2040 return sb.toString(); 2041 } 2042 2043 /** 2044 * Creates a {@code String} representation of the {@code byte[]} passed. The 2045 * result is surrounded by brackets ({@code "[]"}), each element 2046 * is converted to a {@code String} via the {@link String#valueOf(int)} and 2047 * separated by {@code ", "}. If the array is {@code null}, then 2048 * {@code "null"} is returned. 2049 * 2050 * @param array 2051 * the {@code byte} array to convert. 2052 * @return the {@code String} representation of {@code array}. 2053 * @since 1.5 2054 */ toString(byte[] array)2055 public static String toString(byte[] array) { 2056 if (array == null) { 2057 return "null"; 2058 } 2059 if (array.length == 0) { 2060 return "[]"; 2061 } 2062 StringBuilder sb = new StringBuilder(array.length * 6); 2063 sb.append('['); 2064 sb.append(array[0]); 2065 for (int i = 1; i < array.length; i++) { 2066 sb.append(", "); 2067 sb.append(array[i]); 2068 } 2069 sb.append(']'); 2070 return sb.toString(); 2071 } 2072 2073 /** 2074 * Creates a {@code String} representation of the {@code char[]} passed. The 2075 * result is surrounded by brackets ({@code "[]"}), each element 2076 * is converted to a {@code String} via the {@link String#valueOf(char)} and 2077 * separated by {@code ", "}. If the array is {@code null}, then 2078 * {@code "null"} is returned. 2079 * 2080 * @param array 2081 * the {@code char} array to convert. 2082 * @return the {@code String} representation of {@code array}. 2083 * @since 1.5 2084 */ toString(char[] array)2085 public static String toString(char[] array) { 2086 if (array == null) { 2087 return "null"; 2088 } 2089 if (array.length == 0) { 2090 return "[]"; 2091 } 2092 StringBuilder sb = new StringBuilder(array.length * 3); 2093 sb.append('['); 2094 sb.append(array[0]); 2095 for (int i = 1; i < array.length; i++) { 2096 sb.append(", "); 2097 sb.append(array[i]); 2098 } 2099 sb.append(']'); 2100 return sb.toString(); 2101 } 2102 2103 /** 2104 * Creates a {@code String} representation of the {@code double[]} passed. 2105 * The result is surrounded by brackets ({@code "[]"}), each 2106 * element is converted to a {@code String} via the 2107 * {@link String#valueOf(double)} and separated by {@code ", "}. 2108 * If the array is {@code null}, then {@code "null"} is returned. 2109 * 2110 * @param array 2111 * the {@code double} array to convert. 2112 * @return the {@code String} representation of {@code array}. 2113 * @since 1.5 2114 */ toString(double[] array)2115 public static String toString(double[] array) { 2116 if (array == null) { 2117 return "null"; 2118 } 2119 if (array.length == 0) { 2120 return "[]"; 2121 } 2122 StringBuilder sb = new StringBuilder(array.length * 7); 2123 sb.append('['); 2124 sb.append(array[0]); 2125 for (int i = 1; i < array.length; i++) { 2126 sb.append(", "); 2127 sb.append(array[i]); 2128 } 2129 sb.append(']'); 2130 return sb.toString(); 2131 } 2132 2133 /** 2134 * Creates a {@code String} representation of the {@code float[]} passed. 2135 * The result is surrounded by brackets ({@code "[]"}), each 2136 * element is converted to a {@code String} via the 2137 * {@link String#valueOf(float)} and separated by {@code ", "}. 2138 * If the array is {@code null}, then {@code "null"} is returned. 2139 * 2140 * @param array 2141 * the {@code float} array to convert. 2142 * @return the {@code String} representation of {@code array}. 2143 * @since 1.5 2144 */ toString(float[] array)2145 public static String toString(float[] array) { 2146 if (array == null) { 2147 return "null"; 2148 } 2149 if (array.length == 0) { 2150 return "[]"; 2151 } 2152 StringBuilder sb = new StringBuilder(array.length * 7); 2153 sb.append('['); 2154 sb.append(array[0]); 2155 for (int i = 1; i < array.length; i++) { 2156 sb.append(", "); 2157 sb.append(array[i]); 2158 } 2159 sb.append(']'); 2160 return sb.toString(); 2161 } 2162 2163 /** 2164 * Creates a {@code String} representation of the {@code int[]} passed. The 2165 * result is surrounded by brackets ({@code "[]"}), each element 2166 * is converted to a {@code String} via the {@link String#valueOf(int)} and 2167 * separated by {@code ", "}. If the array is {@code null}, then 2168 * {@code "null"} is returned. 2169 * 2170 * @param array 2171 * the {@code int} array to convert. 2172 * @return the {@code String} representation of {@code array}. 2173 * @since 1.5 2174 */ toString(int[] array)2175 public static String toString(int[] array) { 2176 if (array == null) { 2177 return "null"; 2178 } 2179 if (array.length == 0) { 2180 return "[]"; 2181 } 2182 StringBuilder sb = new StringBuilder(array.length * 6); 2183 sb.append('['); 2184 sb.append(array[0]); 2185 for (int i = 1; i < array.length; i++) { 2186 sb.append(", "); 2187 sb.append(array[i]); 2188 } 2189 sb.append(']'); 2190 return sb.toString(); 2191 } 2192 2193 /** 2194 * Creates a {@code String} representation of the {@code long[]} passed. The 2195 * result is surrounded by brackets ({@code "[]"}), each element 2196 * is converted to a {@code String} via the {@link String#valueOf(long)} and 2197 * separated by {@code ", "}. If the array is {@code null}, then 2198 * {@code "null"} is returned. 2199 * 2200 * @param array 2201 * the {@code long} array to convert. 2202 * @return the {@code String} representation of {@code array}. 2203 * @since 1.5 2204 */ toString(long[] array)2205 public static String toString(long[] array) { 2206 if (array == null) { 2207 return "null"; 2208 } 2209 if (array.length == 0) { 2210 return "[]"; 2211 } 2212 StringBuilder sb = new StringBuilder(array.length * 6); 2213 sb.append('['); 2214 sb.append(array[0]); 2215 for (int i = 1; i < array.length; i++) { 2216 sb.append(", "); 2217 sb.append(array[i]); 2218 } 2219 sb.append(']'); 2220 return sb.toString(); 2221 } 2222 2223 /** 2224 * Creates a {@code String} representation of the {@code short[]} passed. 2225 * The result is surrounded by brackets ({@code "[]"}), each 2226 * element is converted to a {@code String} via the 2227 * {@link String#valueOf(int)} and separated by {@code ", "}. If 2228 * the array is {@code null}, then {@code "null"} is returned. 2229 * 2230 * @param array 2231 * the {@code short} array to convert. 2232 * @return the {@code String} representation of {@code array}. 2233 * @since 1.5 2234 */ toString(short[] array)2235 public static String toString(short[] array) { 2236 if (array == null) { 2237 return "null"; 2238 } 2239 if (array.length == 0) { 2240 return "[]"; 2241 } 2242 StringBuilder sb = new StringBuilder(array.length * 6); 2243 sb.append('['); 2244 sb.append(array[0]); 2245 for (int i = 1; i < array.length; i++) { 2246 sb.append(", "); 2247 sb.append(array[i]); 2248 } 2249 sb.append(']'); 2250 return sb.toString(); 2251 } 2252 2253 /** 2254 * Creates a {@code String} representation of the {@code Object[]} passed. 2255 * The result is surrounded by brackets ({@code "[]"}), each 2256 * element is converted to a {@code String} via the 2257 * {@link String#valueOf(Object)} and separated by {@code ", "}. 2258 * If the array is {@code null}, then {@code "null"} is returned. 2259 * 2260 * @param array 2261 * the {@code Object} array to convert. 2262 * @return the {@code String} representation of {@code array}. 2263 * @since 1.5 2264 */ toString(Object[] array)2265 public static String toString(Object[] array) { 2266 if (array == null) { 2267 return "null"; 2268 } 2269 if (array.length == 0) { 2270 return "[]"; 2271 } 2272 StringBuilder sb = new StringBuilder(array.length * 7); 2273 sb.append('['); 2274 sb.append(array[0]); 2275 for (int i = 1; i < array.length; i++) { 2276 sb.append(", "); 2277 sb.append(array[i]); 2278 } 2279 sb.append(']'); 2280 return sb.toString(); 2281 } 2282 2283 /** 2284 * Creates a <i>"deep"</i> {@code String} representation of the 2285 * {@code Object[]} passed, such that if the array contains other arrays, 2286 * the {@code String} representation of those arrays is generated as well. 2287 * <p> 2288 * If any of the elements are primitive arrays, the generation is delegated 2289 * to the other {@code toString} methods in this class. If any element 2290 * contains a reference to the original array, then it will be represented 2291 * as {@code "[...]"}. If an element is an {@code Object[]}, then its 2292 * representation is generated by a recursive call to this method. All other 2293 * elements are converted via the {@link String#valueOf(Object)} method. 2294 * 2295 * @param array 2296 * the {@code Object} array to convert. 2297 * @return the {@code String} representation of {@code array}. 2298 * @since 1.5 2299 */ deepToString(Object[] array)2300 public static String deepToString(Object[] array) { 2301 // Special case null to prevent NPE 2302 if (array == null) { 2303 return "null"; 2304 } 2305 // delegate this to the recursive method 2306 StringBuilder buf = new StringBuilder(array.length * 9); 2307 deepToStringImpl(array, new Object[] { array }, buf); 2308 return buf.toString(); 2309 } 2310 2311 /** 2312 * Implementation method used by {@link #deepToString(Object[])}. 2313 * 2314 * @param array 2315 * the {@code Object[]} to dive into. 2316 * @param origArrays 2317 * the original {@code Object[]}; used to test for self 2318 * references. 2319 * @param sb 2320 * the {@code StringBuilder} instance to append to or 2321 * {@code null} one hasn't been created yet. 2322 * @return the result. 2323 * @see #deepToString(Object[]) 2324 */ deepToStringImpl(Object[] array, Object[] origArrays, StringBuilder sb)2325 private static void deepToStringImpl(Object[] array, Object[] origArrays, 2326 StringBuilder sb) { 2327 if (array == null) { 2328 sb.append("null"); 2329 return; 2330 } 2331 2332 sb.append('['); 2333 2334 for (int i = 0; i < array.length; i++) { 2335 if (i != 0) { 2336 sb.append(", "); 2337 } 2338 // establish current element 2339 Object elem = array[i]; 2340 if (elem == null) { 2341 // element is null 2342 sb.append("null"); 2343 } else { 2344 // get the Class of the current element 2345 Class<?> elemClass = elem.getClass(); 2346 if (elemClass.isArray()) { 2347 // element is an array type 2348 2349 // get the declared Class of the array (element) 2350 Class<?> elemElemClass = elemClass.getComponentType(); 2351 if (elemElemClass.isPrimitive()) { 2352 // element is a primitive array 2353 if (boolean.class.equals(elemElemClass)) { 2354 sb.append(toString((boolean[]) elem)); 2355 } else if (byte.class.equals(elemElemClass)) { 2356 sb.append(toString((byte[]) elem)); 2357 } else if (char.class.equals(elemElemClass)) { 2358 sb.append(toString((char[]) elem)); 2359 } else if (double.class.equals(elemElemClass)) { 2360 sb.append(toString((double[]) elem)); 2361 } else if (float.class.equals(elemElemClass)) { 2362 sb.append(toString((float[]) elem)); 2363 } else if (int.class.equals(elemElemClass)) { 2364 sb.append(toString((int[]) elem)); 2365 } else if (long.class.equals(elemElemClass)) { 2366 sb.append(toString((long[]) elem)); 2367 } else if (short.class.equals(elemElemClass)) { 2368 sb.append(toString((short[]) elem)); 2369 } else { 2370 // no other possible primitives, so we assert that 2371 throw new AssertionError(); 2372 } 2373 } else { 2374 // element is an Object[], so we assert that 2375 // assert elem instanceof Object[]; 2376 if (deepToStringImplContains(origArrays, elem)) { 2377 sb.append("[...]"); 2378 } else { 2379 Object[] newArray = (Object[]) elem; 2380 Object[] newOrigArrays = new Object[origArrays.length + 1]; 2381 System.arraycopy(origArrays, 0, newOrigArrays, 0, 2382 origArrays.length); 2383 newOrigArrays[origArrays.length] = newArray; 2384 // make the recursive call to this method 2385 deepToStringImpl(newArray, newOrigArrays, sb); 2386 } 2387 } 2388 } else { // element is NOT an array, just an Object 2389 sb.append(array[i]); 2390 } 2391 } 2392 } 2393 sb.append(']'); 2394 } 2395 2396 /** 2397 * Utility method used to assist the implementation of 2398 * {@link #deepToString(Object[])}. 2399 * 2400 * @param origArrays 2401 * An array of Object[] references. 2402 * @param array 2403 * An Object[] reference to look for in {@code origArrays}. 2404 * @return A value of {@code true} if {@code array} is an 2405 * element in {@code origArrays}. 2406 */ deepToStringImplContains(Object[] origArrays, Object array)2407 private static boolean deepToStringImplContains(Object[] origArrays, 2408 Object array) { 2409 if (origArrays == null || origArrays.length == 0) { 2410 return false; 2411 } 2412 for (Object element : origArrays) { 2413 if (element == array) { 2414 return true; 2415 } 2416 } 2417 return false; 2418 } 2419 2420 /** 2421 * Copies {@code newLength} elements from {@code original} into a new array. 2422 * If {@code newLength} is greater than {@code original.length}, the result is padded 2423 * with the value {@code false}. 2424 * 2425 * @param original the original array 2426 * @param newLength the length of the new array 2427 * @return the new array 2428 * @throws NegativeArraySizeException if {@code newLength < 0} 2429 * @throws NullPointerException if {@code original == null} 2430 * @since 1.6 2431 */ copyOf(boolean[] original, int newLength)2432 public static boolean[] copyOf(boolean[] original, int newLength) { 2433 if (newLength < 0) { 2434 throw new NegativeArraySizeException(Integer.toString(newLength)); 2435 } 2436 return copyOfRange(original, 0, newLength); 2437 } 2438 2439 /** 2440 * Copies {@code newLength} elements from {@code original} into a new array. 2441 * If {@code newLength} is greater than {@code original.length}, the result is padded 2442 * with the value {@code (byte) 0}. 2443 * 2444 * @param original the original array 2445 * @param newLength the length of the new array 2446 * @return the new array 2447 * @throws NegativeArraySizeException if {@code newLength < 0} 2448 * @throws NullPointerException if {@code original == null} 2449 * @since 1.6 2450 */ copyOf(byte[] original, int newLength)2451 public static byte[] copyOf(byte[] original, int newLength) { 2452 if (newLength < 0) { 2453 throw new NegativeArraySizeException(Integer.toString(newLength)); 2454 } 2455 return copyOfRange(original, 0, newLength); 2456 } 2457 2458 /** 2459 * Copies {@code newLength} elements from {@code original} into a new array. 2460 * If {@code newLength} is greater than {@code original.length}, the result is padded 2461 * with the value {@code '\\u0000'}. 2462 * 2463 * @param original the original array 2464 * @param newLength the length of the new array 2465 * @return the new array 2466 * @throws NegativeArraySizeException if {@code newLength < 0} 2467 * @throws NullPointerException if {@code original == null} 2468 * @since 1.6 2469 */ copyOf(char[] original, int newLength)2470 public static char[] copyOf(char[] original, int newLength) { 2471 if (newLength < 0) { 2472 throw new NegativeArraySizeException(Integer.toString(newLength)); 2473 } 2474 return copyOfRange(original, 0, newLength); 2475 } 2476 2477 /** 2478 * Copies {@code newLength} elements from {@code original} into a new array. 2479 * If {@code newLength} is greater than {@code original.length}, the result is padded 2480 * with the value {@code 0.0d}. 2481 * 2482 * @param original the original array 2483 * @param newLength the length of the new array 2484 * @return the new array 2485 * @throws NegativeArraySizeException if {@code newLength < 0} 2486 * @throws NullPointerException if {@code original == null} 2487 * @since 1.6 2488 */ copyOf(double[] original, int newLength)2489 public static double[] copyOf(double[] original, int newLength) { 2490 if (newLength < 0) { 2491 throw new NegativeArraySizeException(Integer.toString(newLength)); 2492 } 2493 return copyOfRange(original, 0, newLength); 2494 } 2495 2496 /** 2497 * Copies {@code newLength} elements from {@code original} into a new array. 2498 * If {@code newLength} is greater than {@code original.length}, the result is padded 2499 * with the value {@code 0.0f}. 2500 * 2501 * @param original the original array 2502 * @param newLength the length of the new array 2503 * @return the new array 2504 * @throws NegativeArraySizeException if {@code newLength < 0} 2505 * @throws NullPointerException if {@code original == null} 2506 * @since 1.6 2507 */ copyOf(float[] original, int newLength)2508 public static float[] copyOf(float[] original, int newLength) { 2509 if (newLength < 0) { 2510 throw new NegativeArraySizeException(Integer.toString(newLength)); 2511 } 2512 return copyOfRange(original, 0, newLength); 2513 } 2514 2515 /** 2516 * Copies {@code newLength} elements from {@code original} into a new array. 2517 * If {@code newLength} is greater than {@code original.length}, the result is padded 2518 * with the value {@code 0}. 2519 * 2520 * @param original the original array 2521 * @param newLength the length of the new array 2522 * @return the new array 2523 * @throws NegativeArraySizeException if {@code newLength < 0} 2524 * @throws NullPointerException if {@code original == null} 2525 * @since 1.6 2526 */ copyOf(int[] original, int newLength)2527 public static int[] copyOf(int[] original, int newLength) { 2528 if (newLength < 0) { 2529 throw new NegativeArraySizeException(Integer.toString(newLength)); 2530 } 2531 return copyOfRange(original, 0, newLength); 2532 } 2533 2534 /** 2535 * Copies {@code newLength} elements from {@code original} into a new array. 2536 * If {@code newLength} is greater than {@code original.length}, the result is padded 2537 * with the value {@code 0L}. 2538 * 2539 * @param original the original array 2540 * @param newLength the length of the new array 2541 * @return the new array 2542 * @throws NegativeArraySizeException if {@code newLength < 0} 2543 * @throws NullPointerException if {@code original == null} 2544 * @since 1.6 2545 */ copyOf(long[] original, int newLength)2546 public static long[] copyOf(long[] original, int newLength) { 2547 if (newLength < 0) { 2548 throw new NegativeArraySizeException(Integer.toString(newLength)); 2549 } 2550 return copyOfRange(original, 0, newLength); 2551 } 2552 2553 /** 2554 * Copies {@code newLength} elements from {@code original} into a new array. 2555 * If {@code newLength} is greater than {@code original.length}, the result is padded 2556 * with the value {@code (short) 0}. 2557 * 2558 * @param original the original array 2559 * @param newLength the length of the new array 2560 * @return the new array 2561 * @throws NegativeArraySizeException if {@code newLength < 0} 2562 * @throws NullPointerException if {@code original == null} 2563 * @since 1.6 2564 */ copyOf(short[] original, int newLength)2565 public static short[] copyOf(short[] original, int newLength) { 2566 if (newLength < 0) { 2567 throw new NegativeArraySizeException(Integer.toString(newLength)); 2568 } 2569 return copyOfRange(original, 0, newLength); 2570 } 2571 2572 /** 2573 * Copies {@code newLength} elements from {@code original} into a new array. 2574 * If {@code newLength} is greater than {@code original.length}, the result is padded 2575 * with the value {@code null}. 2576 * 2577 * @param original the original array 2578 * @param newLength the length of the new array 2579 * @return the new array 2580 * @throws NegativeArraySizeException if {@code newLength < 0} 2581 * @throws NullPointerException if {@code original == null} 2582 * @since 1.6 2583 */ copyOf(T[] original, int newLength)2584 public static <T> T[] copyOf(T[] original, int newLength) { 2585 if (original == null) { 2586 throw new NullPointerException("original == null"); 2587 } 2588 if (newLength < 0) { 2589 throw new NegativeArraySizeException(Integer.toString(newLength)); 2590 } 2591 return copyOfRange(original, 0, newLength); 2592 } 2593 2594 /** 2595 * Copies {@code newLength} elements from {@code original} into a new array. 2596 * If {@code newLength} is greater than {@code original.length}, the result is padded 2597 * with the value {@code null}. 2598 * 2599 * @param original the original array 2600 * @param newLength the length of the new array 2601 * @param newType the class of the new array 2602 * @return the new array 2603 * @throws NegativeArraySizeException if {@code newLength < 0} 2604 * @throws NullPointerException if {@code original == null} 2605 * @throws ArrayStoreException if a value in {@code original} is incompatible with T 2606 * @since 1.6 2607 */ copyOf(U[] original, int newLength, Class<? extends T[]> newType)2608 public static <T, U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { 2609 // We use the null pointer check in copyOfRange for exception priority compatibility. 2610 if (newLength < 0) { 2611 throw new NegativeArraySizeException(Integer.toString(newLength)); 2612 } 2613 return copyOfRange(original, 0, newLength, newType); 2614 } 2615 2616 /** 2617 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2618 * end (exclusive). The original order of elements is preserved. 2619 * If {@code end} is greater than {@code original.length}, the result is padded 2620 * with the value {@code false}. 2621 * 2622 * @param original the original array 2623 * @param start the start index, inclusive 2624 * @param end the end index, exclusive 2625 * @return the new array 2626 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2627 * @throws IllegalArgumentException if {@code start > end} 2628 * @throws NullPointerException if {@code original == null} 2629 * @since 1.6 2630 */ copyOfRange(boolean[] original, int start, int end)2631 public static boolean[] copyOfRange(boolean[] original, int start, int end) { 2632 if (start > end) { 2633 throw new IllegalArgumentException(); 2634 } 2635 int originalLength = original.length; 2636 if (start < 0 || start > originalLength) { 2637 throw new ArrayIndexOutOfBoundsException(); 2638 } 2639 int resultLength = end - start; 2640 int copyLength = Math.min(resultLength, originalLength - start); 2641 boolean[] result = new boolean[resultLength]; 2642 System.arraycopy(original, start, result, 0, copyLength); 2643 return result; 2644 } 2645 2646 /** 2647 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2648 * end (exclusive). The original order of elements is preserved. 2649 * If {@code end} is greater than {@code original.length}, the result is padded 2650 * with the value {@code (byte) 0}. 2651 * 2652 * @param original the original array 2653 * @param start the start index, inclusive 2654 * @param end the end index, exclusive 2655 * @return the new array 2656 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2657 * @throws IllegalArgumentException if {@code start > end} 2658 * @throws NullPointerException if {@code original == null} 2659 * @since 1.6 2660 */ copyOfRange(byte[] original, int start, int end)2661 public static byte[] copyOfRange(byte[] original, int start, int end) { 2662 if (start > end) { 2663 throw new IllegalArgumentException(); 2664 } 2665 int originalLength = original.length; 2666 if (start < 0 || start > originalLength) { 2667 throw new ArrayIndexOutOfBoundsException(); 2668 } 2669 int resultLength = end - start; 2670 int copyLength = Math.min(resultLength, originalLength - start); 2671 byte[] result = new byte[resultLength]; 2672 System.arraycopy(original, start, result, 0, copyLength); 2673 return result; 2674 } 2675 2676 /** 2677 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2678 * end (exclusive). The original order of elements is preserved. 2679 * If {@code end} is greater than {@code original.length}, the result is padded 2680 * with the value {@code '\\u0000'}. 2681 * 2682 * @param original the original array 2683 * @param start the start index, inclusive 2684 * @param end the end index, exclusive 2685 * @return the new array 2686 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2687 * @throws IllegalArgumentException if {@code start > end} 2688 * @throws NullPointerException if {@code original == null} 2689 * @since 1.6 2690 */ copyOfRange(char[] original, int start, int end)2691 public static char[] copyOfRange(char[] original, int start, int end) { 2692 if (start > end) { 2693 throw new IllegalArgumentException(); 2694 } 2695 int originalLength = original.length; 2696 if (start < 0 || start > originalLength) { 2697 throw new ArrayIndexOutOfBoundsException(); 2698 } 2699 int resultLength = end - start; 2700 int copyLength = Math.min(resultLength, originalLength - start); 2701 char[] result = new char[resultLength]; 2702 System.arraycopy(original, start, result, 0, copyLength); 2703 return result; 2704 } 2705 2706 /** 2707 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2708 * end (exclusive). The original order of elements is preserved. 2709 * If {@code end} is greater than {@code original.length}, the result is padded 2710 * with the value {@code 0.0d}. 2711 * 2712 * @param original the original array 2713 * @param start the start index, inclusive 2714 * @param end the end index, exclusive 2715 * @return the new array 2716 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2717 * @throws IllegalArgumentException if {@code start > end} 2718 * @throws NullPointerException if {@code original == null} 2719 * @since 1.6 2720 */ copyOfRange(double[] original, int start, int end)2721 public static double[] copyOfRange(double[] original, int start, int end) { 2722 if (start > end) { 2723 throw new IllegalArgumentException(); 2724 } 2725 int originalLength = original.length; 2726 if (start < 0 || start > originalLength) { 2727 throw new ArrayIndexOutOfBoundsException(); 2728 } 2729 int resultLength = end - start; 2730 int copyLength = Math.min(resultLength, originalLength - start); 2731 double[] result = new double[resultLength]; 2732 System.arraycopy(original, start, result, 0, copyLength); 2733 return result; 2734 } 2735 2736 /** 2737 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2738 * end (exclusive). The original order of elements is preserved. 2739 * If {@code end} is greater than {@code original.length}, the result is padded 2740 * with the value {@code 0.0f}. 2741 * 2742 * @param original the original array 2743 * @param start the start index, inclusive 2744 * @param end the end index, exclusive 2745 * @return the new array 2746 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2747 * @throws IllegalArgumentException if {@code start > end} 2748 * @throws NullPointerException if {@code original == null} 2749 * @since 1.6 2750 */ copyOfRange(float[] original, int start, int end)2751 public static float[] copyOfRange(float[] original, int start, int end) { 2752 if (start > end) { 2753 throw new IllegalArgumentException(); 2754 } 2755 int originalLength = original.length; 2756 if (start < 0 || start > originalLength) { 2757 throw new ArrayIndexOutOfBoundsException(); 2758 } 2759 int resultLength = end - start; 2760 int copyLength = Math.min(resultLength, originalLength - start); 2761 float[] result = new float[resultLength]; 2762 System.arraycopy(original, start, result, 0, copyLength); 2763 return result; 2764 } 2765 2766 /** 2767 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2768 * end (exclusive). The original order of elements is preserved. 2769 * If {@code end} is greater than {@code original.length}, the result is padded 2770 * with the value {@code 0}. 2771 * 2772 * @param original the original array 2773 * @param start the start index, inclusive 2774 * @param end the end index, exclusive 2775 * @return the new array 2776 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2777 * @throws IllegalArgumentException if {@code start > end} 2778 * @throws NullPointerException if {@code original == null} 2779 * @since 1.6 2780 */ copyOfRange(int[] original, int start, int end)2781 public static int[] copyOfRange(int[] original, int start, int end) { 2782 if (start > end) { 2783 throw new IllegalArgumentException(); 2784 } 2785 int originalLength = original.length; 2786 if (start < 0 || start > originalLength) { 2787 throw new ArrayIndexOutOfBoundsException(); 2788 } 2789 int resultLength = end - start; 2790 int copyLength = Math.min(resultLength, originalLength - start); 2791 int[] result = new int[resultLength]; 2792 System.arraycopy(original, start, result, 0, copyLength); 2793 return result; 2794 } 2795 2796 /** 2797 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2798 * end (exclusive). The original order of elements is preserved. 2799 * If {@code end} is greater than {@code original.length}, the result is padded 2800 * with the value {@code 0L}. 2801 * 2802 * @param original the original array 2803 * @param start the start index, inclusive 2804 * @param end the end index, exclusive 2805 * @return the new array 2806 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2807 * @throws IllegalArgumentException if {@code start > end} 2808 * @throws NullPointerException if {@code original == null} 2809 * @since 1.6 2810 */ copyOfRange(long[] original, int start, int end)2811 public static long[] copyOfRange(long[] original, int start, int end) { 2812 if (start > end) { 2813 throw new IllegalArgumentException(); 2814 } 2815 int originalLength = original.length; 2816 if (start < 0 || start > originalLength) { 2817 throw new ArrayIndexOutOfBoundsException(); 2818 } 2819 int resultLength = end - start; 2820 int copyLength = Math.min(resultLength, originalLength - start); 2821 long[] result = new long[resultLength]; 2822 System.arraycopy(original, start, result, 0, copyLength); 2823 return result; 2824 } 2825 2826 /** 2827 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2828 * end (exclusive). The original order of elements is preserved. 2829 * If {@code end} is greater than {@code original.length}, the result is padded 2830 * with the value {@code (short) 0}. 2831 * 2832 * @param original the original array 2833 * @param start the start index, inclusive 2834 * @param end the end index, exclusive 2835 * @return the new array 2836 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2837 * @throws IllegalArgumentException if {@code start > end} 2838 * @throws NullPointerException if {@code original == null} 2839 * @since 1.6 2840 */ copyOfRange(short[] original, int start, int end)2841 public static short[] copyOfRange(short[] original, int start, int end) { 2842 if (start > end) { 2843 throw new IllegalArgumentException(); 2844 } 2845 int originalLength = original.length; 2846 if (start < 0 || start > originalLength) { 2847 throw new ArrayIndexOutOfBoundsException(); 2848 } 2849 int resultLength = end - start; 2850 int copyLength = Math.min(resultLength, originalLength - start); 2851 short[] result = new short[resultLength]; 2852 System.arraycopy(original, start, result, 0, copyLength); 2853 return result; 2854 } 2855 2856 /** 2857 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2858 * end (exclusive). The original order of elements is preserved. 2859 * If {@code end} is greater than {@code original.length}, the result is padded 2860 * with the value {@code null}. 2861 * 2862 * @param original the original array 2863 * @param start the start index, inclusive 2864 * @param end the end index, exclusive 2865 * @return the new array 2866 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2867 * @throws IllegalArgumentException if {@code start > end} 2868 * @throws NullPointerException if {@code original == null} 2869 * @since 1.6 2870 */ 2871 @SuppressWarnings("unchecked") copyOfRange(T[] original, int start, int end)2872 public static <T> T[] copyOfRange(T[] original, int start, int end) { 2873 int originalLength = original.length; // For exception priority compatibility. 2874 if (start > end) { 2875 throw new IllegalArgumentException(); 2876 } 2877 if (start < 0 || start > originalLength) { 2878 throw new ArrayIndexOutOfBoundsException(); 2879 } 2880 int resultLength = end - start; 2881 int copyLength = Math.min(resultLength, originalLength - start); 2882 T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), resultLength); 2883 System.arraycopy(original, start, result, 0, copyLength); 2884 return result; 2885 } 2886 2887 /** 2888 * Copies elements from {@code original} into a new array, from indexes start (inclusive) to 2889 * end (exclusive). The original order of elements is preserved. 2890 * If {@code end} is greater than {@code original.length}, the result is padded 2891 * with the value {@code null}. 2892 * 2893 * @param original the original array 2894 * @param start the start index, inclusive 2895 * @param end the end index, exclusive 2896 * @return the new array 2897 * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length} 2898 * @throws IllegalArgumentException if {@code start > end} 2899 * @throws NullPointerException if {@code original == null} 2900 * @throws ArrayStoreException if a value in {@code original} is incompatible with T 2901 * @since 1.6 2902 */ 2903 @SuppressWarnings("unchecked") copyOfRange(U[] original, int start, int end, Class<? extends T[]> newType)2904 public static <T, U> T[] copyOfRange(U[] original, int start, int end, Class<? extends T[]> newType) { 2905 if (start > end) { 2906 throw new IllegalArgumentException(); 2907 } 2908 int originalLength = original.length; 2909 if (start < 0 || start > originalLength) { 2910 throw new ArrayIndexOutOfBoundsException(); 2911 } 2912 int resultLength = end - start; 2913 int copyLength = Math.min(resultLength, originalLength - start); 2914 T[] result = (T[]) Array.newInstance(newType.getComponentType(), resultLength); 2915 System.arraycopy(original, start, result, 0, copyLength); 2916 return result; 2917 } 2918 } 2919