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 * https://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 package org.apache.commons.lang3;
18
19 import java.lang.reflect.Array;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Type;
23 import java.security.SecureRandom;
24 import java.util.Arrays;
25 import java.util.BitSet;
26 import java.util.Comparator;
27 import java.util.Date;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.Objects;
31 import java.util.Random;
32 import java.util.concurrent.ThreadLocalRandom;
33 import java.util.function.Function;
34 import java.util.function.IntFunction;
35 import java.util.function.Supplier;
36
37 import org.apache.commons.lang3.builder.EqualsBuilder;
38 import org.apache.commons.lang3.builder.HashCodeBuilder;
39 import org.apache.commons.lang3.builder.ToStringBuilder;
40 import org.apache.commons.lang3.builder.ToStringStyle;
41 import org.apache.commons.lang3.function.FailableFunction;
42 import org.apache.commons.lang3.mutable.MutableInt;
43 import org.apache.commons.lang3.stream.IntStreams;
44 import org.apache.commons.lang3.stream.Streams;
45
46 /**
47 * Operations on arrays, primitive arrays (like {@code int[]}) and
48 * primitive wrapper arrays (like {@code Integer[]}).
49 * <p>
50 * This class tries to handle {@code null} input gracefully.
51 * An exception will not be thrown for a {@code null}
52 * array input. However, an Object array that contains a {@code null}
53 * element may throw an exception. Each method documents its behavior.
54 * </p>
55 * <p>
56 * #ThreadSafe#
57 * </p>
58 * @since 2.0
59 */
60 public class ArrayUtils {
61
62 /**
63 * An empty immutable {@code boolean} array.
64 */
65 public static final boolean[] EMPTY_BOOLEAN_ARRAY = {};
66
67 /**
68 * An empty immutable {@link Boolean} array.
69 */
70 public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = {};
71
72 /**
73 * An empty immutable {@code byte} array.
74 */
75 public static final byte[] EMPTY_BYTE_ARRAY = {};
76
77 /**
78 * An empty immutable {@link Byte} array.
79 */
80 public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = {};
81
82 /**
83 * An empty immutable {@code char} array.
84 */
85 public static final char[] EMPTY_CHAR_ARRAY = {};
86
87 /**
88 * An empty immutable {@link Character} array.
89 */
90 public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = {};
91
92 /**
93 * An empty immutable {@link Class} array.
94 */
95 public static final Class<?>[] EMPTY_CLASS_ARRAY = {};
96
97 /**
98 * An empty immutable {@code double} array.
99 */
100 public static final double[] EMPTY_DOUBLE_ARRAY = {};
101
102 /**
103 * An empty immutable {@link Double} array.
104 */
105 public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = {};
106
107 /**
108 * An empty immutable {@link Field} array.
109 *
110 * @since 3.10
111 */
112 public static final Field[] EMPTY_FIELD_ARRAY = {};
113
114 /**
115 * An empty immutable {@code float} array.
116 */
117 public static final float[] EMPTY_FLOAT_ARRAY = {};
118
119 /**
120 * An empty immutable {@link Float} array.
121 */
122 public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = {};
123
124 /**
125 * An empty immutable {@code int} array.
126 */
127 public static final int[] EMPTY_INT_ARRAY = {};
128
129 /**
130 * An empty immutable {@link Integer} array.
131 */
132 public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = {};
133
134 /**
135 * An empty immutable {@code long} array.
136 */
137 public static final long[] EMPTY_LONG_ARRAY = {};
138
139 /**
140 * An empty immutable {@link Long} array.
141 */
142 public static final Long[] EMPTY_LONG_OBJECT_ARRAY = {};
143
144 /**
145 * An empty immutable {@link Method} array.
146 *
147 * @since 3.10
148 */
149 public static final Method[] EMPTY_METHOD_ARRAY = {};
150
151 /**
152 * An empty immutable {@link Object} array.
153 */
154 public static final Object[] EMPTY_OBJECT_ARRAY = {};
155
156 /**
157 * An empty immutable {@code short} array.
158 */
159 public static final short[] EMPTY_SHORT_ARRAY = {};
160
161 /**
162 * An empty immutable {@link Short} array.
163 */
164 public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = {};
165
166 /**
167 * An empty immutable {@link String} array.
168 */
169 public static final String[] EMPTY_STRING_ARRAY = {};
170
171 /**
172 * An empty immutable {@link Throwable} array.
173 *
174 * @since 3.10
175 */
176 public static final Throwable[] EMPTY_THROWABLE_ARRAY = {};
177
178 /**
179 * An empty immutable {@link Type} array.
180 *
181 * @since 3.10
182 */
183 public static final Type[] EMPTY_TYPE_ARRAY = {};
184
185 /**
186 * The index value when an element is not found in a list or array: {@code -1}.
187 * This value is returned by methods in this class and can also be used in comparisons with values returned by
188 * various method from {@link java.util.List}.
189 */
190 public static final int INDEX_NOT_FOUND = -1;
191
192 /**
193 * The {@code SOFT_MAX_ARRAY_LENGTH} constant from Java's internal ArraySupport class.
194 *
195 * @since 3.19.0
196 */
197 public static int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
198
199 /**
200 * Copies the given array and adds the given element at the end of the new array.
201 * <p>
202 * The new array contains the same elements of the input
203 * array plus the given element in the last position. The component type of
204 * the new array is the same as that of the input array.
205 * </p>
206 * <p>
207 * If the input array is {@code null}, a new one element array is returned
208 * whose component type is the same as the element.
209 * </p>
210 * <pre>
211 * ArrayUtils.add(null, true) = [true]
212 * ArrayUtils.add([true], false) = [true, false]
213 * ArrayUtils.add([true, false], true) = [true, false, true]
214 * </pre>
215 *
216 * @param array the array to copy and add the element to, may be {@code null}
217 * @param element the object to add at the last index of the new array
218 * @return A new array containing the existing elements plus the new element
219 * @since 2.1
220 */
221 public static boolean[] add(final boolean[] array, final boolean element) {
222 final boolean[] newArray = (boolean[]) copyArrayGrow1(array, Boolean.TYPE);
223 newArray[newArray.length - 1] = element;
224 return newArray;
225 }
226
227 /**
228 * Inserts the specified element at the specified position in the array.
229 * Shifts the element currently at that position (if any) and any subsequent
230 * elements to the right (adds one to their indices).
231 * <p>
232 * This method returns a new array with the same elements of the input
233 * array plus the given element on the specified position. The component
234 * type of the returned array is always the same as that of the input
235 * array.
236 * </p>
237 * <p>
238 * If the input array is {@code null}, a new one element array is returned
239 * whose component type is the same as the element.
240 * </p>
241 * <pre>
242 * ArrayUtils.add(null, 0, true) = [true]
243 * ArrayUtils.add([true], 0, false) = [false, true]
244 * ArrayUtils.add([false], 1, true) = [false, true]
245 * ArrayUtils.add([true, false], 1, true) = [true, true, false]
246 * </pre>
247 *
248 * @param array the array to add the element to, may be {@code null}
249 * @param index the position of the new object
250 * @param element the object to add
251 * @return A new array containing the existing elements and the new element
252 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > array.length).
253 * @deprecated this method has been superseded by {@link #insert(int, boolean[], boolean...)} and
254 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
255 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
256 */
257 @Deprecated
258 public static boolean[] add(final boolean[] array, final int index, final boolean element) {
259 return (boolean[]) add(array, index, Boolean.valueOf(element), Boolean.TYPE);
260 }
261
262 /**
263 * Copies the given array and adds the given element at the end of the new array.
264 * <p>
265 * The new array contains the same elements of the input
266 * array plus the given element in the last position. The component type of
267 * the new array is the same as that of the input array.
268 * </p>
269 * <p>
270 * If the input array is {@code null}, a new one element array is returned
271 * whose component type is the same as the element.
272 * </p>
273 * <pre>
274 * ArrayUtils.add(null, 0) = [0]
275 * ArrayUtils.add([1], 0) = [1, 0]
276 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
277 * </pre>
278 *
279 * @param array the array to copy and add the element to, may be {@code null}
280 * @param element the object to add at the last index of the new array
281 * @return A new array containing the existing elements plus the new element
282 * @since 2.1
283 */
284 public static byte[] add(final byte[] array, final byte element) {
285 final byte[] newArray = (byte[]) copyArrayGrow1(array, Byte.TYPE);
286 newArray[newArray.length - 1] = element;
287 return newArray;
288 }
289
290 /**
291 * Inserts the specified element at the specified position in the array.
292 * Shifts the element currently at that position (if any) and any subsequent
293 * elements to the right (adds one to their indices).
294 * <p>
295 * This method returns a new array with the same elements of the input
296 * array plus the given element on the specified position. The component
297 * type of the returned array is always the same as that of the input
298 * array.
299 * </p>
300 * <p>
301 * If the input array is {@code null}, a new one element array is returned
302 * whose component type is the same as the element.
303 * </p>
304 * <pre>
305 * ArrayUtils.add([1], 0, 2) = [2, 1]
306 * ArrayUtils.add([2, 6], 2, 3) = [2, 6, 3]
307 * ArrayUtils.add([2, 6], 0, 1) = [1, 2, 6]
308 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
309 * </pre>
310 *
311 * @param array the array to add the element to, may be {@code null}
312 * @param index the position of the new object
313 * @param element the object to add
314 * @return A new array containing the existing elements and the new element
315 * @throws IndexOutOfBoundsException if the index is out of range
316 * (index < 0 || index > array.length).
317 * @deprecated this method has been superseded by {@link #insert(int, byte[], byte...)} and
318 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
319 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
320 */
321 @Deprecated
322 public static byte[] add(final byte[] array, final int index, final byte element) {
323 return (byte[]) add(array, index, Byte.valueOf(element), Byte.TYPE);
324 }
325
326 /**
327 * Copies the given array and adds the given element at the end of the new array.
328 * <p>
329 * The new array contains the same elements of the input
330 * array plus the given element in the last position. The component type of
331 * the new array is the same as that of the input array.
332 * </p>
333 * <p>
334 * If the input array is {@code null}, a new one element array is returned
335 * whose component type is the same as the element.
336 * </p>
337 * <pre>
338 * ArrayUtils.add(null, '0') = ['0']
339 * ArrayUtils.add(['1'], '0') = ['1', '0']
340 * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
341 * </pre>
342 *
343 * @param array the array to copy and add the element to, may be {@code null}
344 * @param element the object to add at the last index of the new array
345 * @return A new array containing the existing elements plus the new element
346 * @since 2.1
347 */
348 public static char[] add(final char[] array, final char element) {
349 final char[] newArray = (char[]) copyArrayGrow1(array, Character.TYPE);
350 newArray[newArray.length - 1] = element;
351 return newArray;
352 }
353
354 /**
355 * Inserts the specified element at the specified position in the array.
356 * Shifts the element currently at that position (if any) and any subsequent
357 * elements to the right (adds one to their indices).
358 * <p>
359 * This method returns a new array with the same elements of the input
360 * array plus the given element on the specified position. The component
361 * type of the returned array is always the same as that of the input
362 * array.
363 * </p>
364 * <p>
365 * If the input array is {@code null}, a new one element array is returned
366 * whose component type is the same as the element.
367 * </p>
368 * <pre>
369 * ArrayUtils.add(null, 0, 'a') = ['a']
370 * ArrayUtils.add(['a'], 0, 'b') = ['b', 'a']
371 * ArrayUtils.add(['a', 'b'], 0, 'c') = ['c', 'a', 'b']
372 * ArrayUtils.add(['a', 'b'], 1, 'k') = ['a', 'k', 'b']
373 * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
374 * </pre>
375 *
376 * @param array the array to add the element to, may be {@code null}
377 * @param index the position of the new object
378 * @param element the object to add
379 * @return A new array containing the existing elements and the new element
380 * @throws IndexOutOfBoundsException if the index is out of range
381 * (index < 0 || index > array.length).
382 * @deprecated this method has been superseded by {@link #insert(int, char[], char...)} and
383 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
384 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
385 */
386 @Deprecated
387 public static char[] add(final char[] array, final int index, final char element) {
388 return (char[]) add(array, index, Character.valueOf(element), Character.TYPE);
389 }
390
391 /**
392 * Copies the given array and adds the given element at the end of the new array.
393 *
394 * <p>
395 * The new array contains the same elements of the input
396 * array plus the given element in the last position. The component type of
397 * the new array is the same as that of the input array.
398 * </p>
399 * <p>
400 * If the input array is {@code null}, a new one element array is returned
401 * whose component type is the same as the element.
402 * </p>
403 * <pre>
404 * ArrayUtils.add(null, 0) = [0]
405 * ArrayUtils.add([1], 0) = [1, 0]
406 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
407 * </pre>
408 *
409 * @param array the array to copy and add the element to, may be {@code null}
410 * @param element the object to add at the last index of the new array
411 * @return A new array containing the existing elements plus the new element
412 * @since 2.1
413 */
414 public static double[] add(final double[] array, final double element) {
415 final double[] newArray = (double[]) copyArrayGrow1(array, Double.TYPE);
416 newArray[newArray.length - 1] = element;
417 return newArray;
418 }
419
420 /**
421 * Inserts the specified element at the specified position in the array.
422 * Shifts the element currently at that position (if any) and any subsequent
423 * elements to the right (adds one to their indices).
424 * <p>
425 * This method returns a new array with the same elements of the input
426 * array plus the given element on the specified position. The component
427 * type of the returned array is always the same as that of the input
428 * array.
429 * </p>
430 * <p>
431 * If the input array is {@code null}, a new one element array is returned
432 * whose component type is the same as the element.
433 * </p>
434 * <pre>
435 * ArrayUtils.add([1.1], 0, 2.2) = [2.2, 1.1]
436 * ArrayUtils.add([2.3, 6.4], 2, 10.5) = [2.3, 6.4, 10.5]
437 * ArrayUtils.add([2.6, 6.7], 0, -4.8) = [-4.8, 2.6, 6.7]
438 * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0) = [2.9, 6.0, 1.0, 0.3]
439 * </pre>
440 *
441 * @param array the array to add the element to, may be {@code null}
442 * @param index the position of the new object
443 * @param element the object to add
444 * @return A new array containing the existing elements and the new element
445 * @throws IndexOutOfBoundsException if the index is out of range
446 * (index < 0 || index > array.length).
447 * @deprecated this method has been superseded by {@link #insert(int, double[], double...)} and
448 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
449 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
450 */
451 @Deprecated
452 public static double[] add(final double[] array, final int index, final double element) {
453 return (double[]) add(array, index, Double.valueOf(element), Double.TYPE);
454 }
455
456 /**
457 * Copies the given array and adds the given element at the end of the new array.
458 * <p>
459 * The new array contains the same elements of the input
460 * array plus the given element in the last position. The component type of
461 * the new array is the same as that of the input array.
462 * </p>
463 * <p>
464 * If the input array is {@code null}, a new one element array is returned
465 * whose component type is the same as the element.
466 * </p>
467 * <pre>
468 * ArrayUtils.add(null, 0) = [0]
469 * ArrayUtils.add([1], 0) = [1, 0]
470 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
471 * </pre>
472 *
473 * @param array the array to copy and add the element to, may be {@code null}
474 * @param element the object to add at the last index of the new array
475 * @return A new array containing the existing elements plus the new element
476 * @since 2.1
477 */
478 public static float[] add(final float[] array, final float element) {
479 final float[] newArray = (float[]) copyArrayGrow1(array, Float.TYPE);
480 newArray[newArray.length - 1] = element;
481 return newArray;
482 }
483
484 /**
485 * Inserts the specified element at the specified position in the array.
486 * Shifts the element currently at that position (if any) and any subsequent
487 * elements to the right (adds one to their indices).
488 * <p>
489 * This method returns a new array with the same elements of the input
490 * array plus the given element on the specified position. The component
491 * type of the returned array is always the same as that of the input
492 * array.
493 * </p>
494 * <p>
495 * If the input array is {@code null}, a new one element array is returned
496 * whose component type is the same as the element.
497 * </p>
498 * <pre>
499 * ArrayUtils.add([1.1f], 0, 2.2f) = [2.2f, 1.1f]
500 * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f) = [2.3f, 6.4f, 10.5f]
501 * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f) = [-4.8f, 2.6f, 6.7f]
502 * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f) = [2.9f, 6.0f, 1.0f, 0.3f]
503 * </pre>
504 *
505 * @param array the array to add the element to, may be {@code null}
506 * @param index the position of the new object
507 * @param element the object to add
508 * @return A new array containing the existing elements and the new element
509 * @throws IndexOutOfBoundsException if the index is out of range
510 * (index < 0 || index > array.length).
511 * @deprecated this method has been superseded by {@link #insert(int, float[], float...)} and
512 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
513 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
514 */
515 @Deprecated
516 public static float[] add(final float[] array, final int index, final float element) {
517 return (float[]) add(array, index, Float.valueOf(element), Float.TYPE);
518 }
519
520 /**
521 * Copies the given array and adds the given element at the end of the new array.
522 * <p>
523 * The new array contains the same elements of the input
524 * array plus the given element in the last position. The component type of
525 * the new array is the same as that of the input array.
526 * </p>
527 * <p>
528 * If the input array is {@code null}, a new one element array is returned
529 * whose component type is the same as the element.
530 * </p>
531 * <pre>
532 * ArrayUtils.add(null, 0) = [0]
533 * ArrayUtils.add([1], 0) = [1, 0]
534 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
535 * </pre>
536 *
537 * @param array the array to copy and add the element to, may be {@code null}
538 * @param element the object to add at the last index of the new array
539 * @return A new array containing the existing elements plus the new element
540 * @since 2.1
541 */
542 public static int[] add(final int[] array, final int element) {
543 final int[] newArray = (int[]) copyArrayGrow1(array, Integer.TYPE);
544 newArray[newArray.length - 1] = element;
545 return newArray;
546 }
547
548 /**
549 * Inserts the specified element at the specified position in the array.
550 * Shifts the element currently at that position (if any) and any subsequent
551 * elements to the right (adds one to their indices).
552 * <p>
553 * This method returns a new array with the same elements of the input
554 * array plus the given element on the specified position. The component
555 * type of the returned array is always the same as that of the input
556 * array.
557 * </p>
558 * <p>
559 * If the input array is {@code null}, a new one element array is returned
560 * whose component type is the same as the element.
561 * </p>
562 * <pre>
563 * ArrayUtils.add([1], 0, 2) = [2, 1]
564 * ArrayUtils.add([2, 6], 2, 10) = [2, 6, 10]
565 * ArrayUtils.add([2, 6], 0, -4) = [-4, 2, 6]
566 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
567 * </pre>
568 *
569 * @param array the array to add the element to, may be {@code null}
570 * @param index the position of the new object
571 * @param element the object to add
572 * @return A new array containing the existing elements and the new element
573 * @throws IndexOutOfBoundsException if the index is out of range
574 * (index < 0 || index > array.length).
575 * @deprecated this method has been superseded by {@link #insert(int, int[], int...)} and
576 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
577 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
578 */
579 @Deprecated
580 public static int[] add(final int[] array, final int index, final int element) {
581 return (int[]) add(array, index, Integer.valueOf(element), Integer.TYPE);
582 }
583
584 /**
585 * Inserts the specified element at the specified position in the array.
586 * Shifts the element currently at that position (if any) and any subsequent
587 * elements to the right (adds one to their indices).
588 * <p>
589 * This method returns a new array with the same elements of the input
590 * array plus the given element on the specified position. The component
591 * type of the returned array is always the same as that of the input
592 * array.
593 * </p>
594 * <p>
595 * If the input array is {@code null}, a new one element array is returned
596 * whose component type is the same as the element.
597 * </p>
598 * <pre>
599 * ArrayUtils.add([1L], 0, 2L) = [2L, 1L]
600 * ArrayUtils.add([2L, 6L], 2, 10L) = [2L, 6L, 10L]
601 * ArrayUtils.add([2L, 6L], 0, -4L) = [-4L, 2L, 6L]
602 * ArrayUtils.add([2L, 6L, 3L], 2, 1L) = [2L, 6L, 1L, 3L]
603 * </pre>
604 *
605 * @param array the array to add the element to, may be {@code null}
606 * @param index the position of the new object
607 * @param element the object to add
608 * @return A new array containing the existing elements and the new element
609 * @throws IndexOutOfBoundsException if the index is out of range
610 * (index < 0 || index > array.length).
611 * @deprecated this method has been superseded by {@link #insert(int, long[], long...)} and
612 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
613 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
614 */
615 @Deprecated
616 public static long[] add(final long[] array, final int index, final long element) {
617 return (long[]) add(array, index, Long.valueOf(element), Long.TYPE);
618 }
619
620 /**
621 * Copies the given array and adds the given element at the end of the new array.
622 * <p>
623 * The new array contains the same elements of the input
624 * array plus the given element in the last position. The component type of
625 * the new array is the same as that of the input array.
626 * </p>
627 * <p>
628 * If the input array is {@code null}, a new one element array is returned
629 * whose component type is the same as the element.
630 * </p>
631 * <pre>
632 * ArrayUtils.add(null, 0) = [0]
633 * ArrayUtils.add([1], 0) = [1, 0]
634 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
635 * </pre>
636 *
637 * @param array the array to copy and add the element to, may be {@code null}
638 * @param element the object to add at the last index of the new array
639 * @return A new array containing the existing elements plus the new element
640 * @since 2.1
641 */
642 public static long[] add(final long[] array, final long element) {
643 final long[] newArray = (long[]) copyArrayGrow1(array, Long.TYPE);
644 newArray[newArray.length - 1] = element;
645 return newArray;
646 }
647
648 /**
649 * Underlying implementation of add(array, index, element) methods.
650 * The last parameter is the class, which may not equal element.getClass
651 * for primitives.
652 *
653 * @param array the array to add the element to, may be {@code null}
654 * @param index the position of the new object
655 * @param element the object to add
656 * @param clazz the type of the element being added
657 * @return A new array containing the existing elements and the new element
658 */
659 private static Object add(final Object array, final int index, final Object element, final Class<?> clazz) {
660 if (array == null) {
661 if (index != 0) {
662 throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
663 }
664 final Object joinedArray = Array.newInstance(clazz, 1);
665 Array.set(joinedArray, 0, element);
666 return joinedArray;
667 }
668 final int length = Array.getLength(array);
669 if (index > length || index < 0) {
670 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
671 }
672 final Object result = arraycopy(array, 0, 0, index, () -> Array.newInstance(clazz, length + 1));
673 Array.set(result, index, element);
674 if (index < length) {
675 System.arraycopy(array, index, result, index + 1, length - index);
676 }
677 return result;
678 }
679
680 /**
681 * Inserts the specified element at the specified position in the array.
682 * Shifts the element currently at that position (if any) and any subsequent
683 * elements to the right (adds one to their indices).
684 * <p>
685 * This method returns a new array with the same elements of the input
686 * array plus the given element on the specified position. The component
687 * type of the returned array is always the same as that of the input
688 * array.
689 * </p>
690 * <p>
691 * If the input array is {@code null}, a new one element array is returned
692 * whose component type is the same as the element.
693 * </p>
694 * <pre>
695 * ArrayUtils.add([1], 0, 2) = [2, 1]
696 * ArrayUtils.add([2, 6], 2, 10) = [2, 6, 10]
697 * ArrayUtils.add([2, 6], 0, -4) = [-4, 2, 6]
698 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
699 * </pre>
700 *
701 * @param array the array to add the element to, may be {@code null}
702 * @param index the position of the new object
703 * @param element the object to add
704 * @return A new array containing the existing elements and the new element
705 * @throws IndexOutOfBoundsException if the index is out of range
706 * (index < 0 || index > array.length).
707 * @deprecated this method has been superseded by {@link #insert(int, short[], short...)} and
708 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
709 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
710 */
711 @Deprecated
712 public static short[] add(final short[] array, final int index, final short element) {
713 return (short[]) add(array, index, Short.valueOf(element), Short.TYPE);
714 }
715
716 /**
717 * Copies the given array and adds the given element at the end of the new array.
718 * <p>
719 * The new array contains the same elements of the input
720 * array plus the given element in the last position. The component type of
721 * the new array is the same as that of the input array.
722 * </p>
723 * <p>
724 * If the input array is {@code null}, a new one element array is returned
725 * whose component type is the same as the element.
726 * </p>
727 * <pre>
728 * ArrayUtils.add(null, 0) = [0]
729 * ArrayUtils.add([1], 0) = [1, 0]
730 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
731 * </pre>
732 *
733 * @param array the array to copy and add the element to, may be {@code null}
734 * @param element the object to add at the last index of the new array
735 * @return A new array containing the existing elements plus the new element
736 * @since 2.1
737 */
738 public static short[] add(final short[] array, final short element) {
739 final short[] newArray = (short[]) copyArrayGrow1(array, Short.TYPE);
740 newArray[newArray.length - 1] = element;
741 return newArray;
742 }
743
744 /**
745 * Inserts the specified element at the specified position in the array.
746 * Shifts the element currently at that position (if any) and any subsequent
747 * elements to the right (adds one to their indices).
748 * <p>
749 * This method returns a new array with the same elements of the input
750 * array plus the given element on the specified position. The component
751 * type of the returned array is always the same as that of the input
752 * array.
753 * </p>
754 * <p>
755 * If the input array is {@code null}, a new one element array is returned
756 * whose component type is the same as the element.
757 * </p>
758 * <pre>
759 * ArrayUtils.add(null, 0, null) = IllegalArgumentException
760 * ArrayUtils.add(null, 0, "a") = ["a"]
761 * ArrayUtils.add(["a"], 1, null) = ["a", null]
762 * ArrayUtils.add(["a"], 1, "b") = ["a", "b"]
763 * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
764 * </pre>
765 *
766 * @param <T> the component type of the array
767 * @param array the array to add the element to, may be {@code null}
768 * @param index the position of the new object
769 * @param element the object to add
770 * @return A new array containing the existing elements and the new element
771 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > array.length).
772 * @throws IllegalArgumentException if both array and element are null
773 * @deprecated this method has been superseded by {@link #insert(int, Object[], Object...) insert(int, T[], T...)} and
774 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
775 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
776 */
777 @Deprecated
778 public static <T> T[] add(final T[] array, final int index, final T element) {
779 final Class<T> clazz;
780 if (array != null) {
781 clazz = getComponentType(array);
782 } else if (element != null) {
783 clazz = ObjectUtils.getClass(element);
784 } else {
785 throw new IllegalArgumentException("Array and element cannot both be null");
786 }
787 return (T[]) add(array, index, element, clazz);
788 }
789
790 /**
791 * Copies the given array and adds the given element at the end of the new array.
792 * <p>
793 * The new array contains the same elements of the input
794 * array plus the given element in the last position. The component type of
795 * the new array is the same as that of the input array.
796 * </p>
797 * <p>
798 * If the input array is {@code null}, a new one element array is returned
799 * whose component type is the same as the element, unless the element itself is null,
800 * in which case the return type is Object[]
801 * </p>
802 * <pre>
803 * ArrayUtils.add(null, null) = IllegalArgumentException
804 * ArrayUtils.add(null, "a") = ["a"]
805 * ArrayUtils.add(["a"], null) = ["a", null]
806 * ArrayUtils.add(["a"], "b") = ["a", "b"]
807 * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
808 * </pre>
809 *
810 * @param <T> the component type of the array
811 * @param array the array to "add" the element to, may be {@code null}
812 * @param element the object to add, may be {@code null}
813 * @return A new array containing the existing elements plus the new element
814 * The returned array type will be that of the input array (unless null),
815 * in which case it will have the same type as the element.
816 * If both are null, an IllegalArgumentException is thrown
817 * @throws IllegalArgumentException if both arguments are null
818 * @since 2.1
819 */
820 public static <T> T[] add(final T[] array, final T element) {
821 final Class<?> type;
822 if (array != null) {
823 type = array.getClass().getComponentType();
824 } else if (element != null) {
825 type = element.getClass();
826 } else {
827 throw new IllegalArgumentException("Arguments cannot both be null");
828 }
829 @SuppressWarnings("unchecked") // type must be T
830 final
831 T[] newArray = (T[]) copyArrayGrow1(array, type);
832 newArray[newArray.length - 1] = element;
833 return newArray;
834 }
835
836 /**
837 * Adds all the elements of the given arrays into a new array.
838 * <p>
839 * The new array contains all of the element of {@code array1} followed
840 * by all of the elements {@code array2}. When an array is returned, it is always
841 * a new array.
842 * </p>
843 * <pre>
844 * ArrayUtils.addAll(array1, null) = cloned copy of array1
845 * ArrayUtils.addAll(null, array2) = cloned copy of array2
846 * ArrayUtils.addAll([], []) = []
847 * ArrayUtils.addAll(null, null) = null
848 * </pre>
849 *
850 * @param array1 the first array whose elements are added to the new array.
851 * @param array2 the second array whose elements are added to the new array.
852 * @return The new boolean[] array or {@code null}.
853 * @since 2.1
854 */
855 public static boolean[] addAll(final boolean[] array1, final boolean... array2) {
856 if (array1 == null) {
857 return clone(array2);
858 }
859 if (array2 == null) {
860 return clone(array1);
861 }
862 final boolean[] joinedArray = new boolean[array1.length + array2.length];
863 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
864 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
865 return joinedArray;
866 }
867
868 /**
869 * Adds all the elements of the given arrays into a new array.
870 * <p>
871 * The new array contains all of the element of {@code array1} followed
872 * by all of the elements {@code array2}. When an array is returned, it is always
873 * a new array.
874 * </p>
875 * <pre>
876 * ArrayUtils.addAll(array1, null) = cloned copy of array1
877 * ArrayUtils.addAll(null, array2) = cloned copy of array2
878 * ArrayUtils.addAll([], []) = []
879 * ArrayUtils.addAll(null, null) = null
880 * </pre>
881 *
882 * @param array1 the first array whose elements are added to the new array.
883 * @param array2 the second array whose elements are added to the new array.
884 * @return The new byte[] array or {@code null}.
885 * @since 2.1
886 */
887 public static byte[] addAll(final byte[] array1, final byte... array2) {
888 if (array1 == null) {
889 return clone(array2);
890 }
891 if (array2 == null) {
892 return clone(array1);
893 }
894 final byte[] joinedArray = new byte[array1.length + array2.length];
895 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
896 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
897 return joinedArray;
898 }
899
900 /**
901 * Adds all the elements of the given arrays into a new array.
902 * <p>
903 * The new array contains all of the element of {@code array1} followed
904 * by all of the elements {@code array2}. When an array is returned, it is always
905 * a new array.
906 * </p>
907 * <pre>
908 * ArrayUtils.addAll(array1, null) = cloned copy of array1
909 * ArrayUtils.addAll(null, array2) = cloned copy of array2
910 * ArrayUtils.addAll([], []) = []
911 * ArrayUtils.addAll(null, null) = null
912 * </pre>
913 *
914 * @param array1 the first array whose elements are added to the new array.
915 * @param array2 the second array whose elements are added to the new array.
916 * @return The new char[] array or {@code null}.
917 * @since 2.1
918 */
919 public static char[] addAll(final char[] array1, final char... array2) {
920 if (array1 == null) {
921 return clone(array2);
922 }
923 if (array2 == null) {
924 return clone(array1);
925 }
926 final char[] joinedArray = new char[array1.length + array2.length];
927 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
928 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
929 return joinedArray;
930 }
931
932 /**
933 * Adds all the elements of the given arrays into a new array.
934 * <p>
935 * The new array contains all of the element of {@code array1} followed
936 * by all of the elements {@code array2}. When an array is returned, it is always
937 * a new array.
938 * </p>
939 * <pre>
940 * ArrayUtils.addAll(array1, null) = cloned copy of array1
941 * ArrayUtils.addAll(null, array2) = cloned copy of array2
942 * ArrayUtils.addAll([], []) = []
943 * ArrayUtils.addAll(null, null) = null
944 * </pre>
945 *
946 * @param array1 the first array whose elements are added to the new array.
947 * @param array2 the second array whose elements are added to the new array.
948 * @return The new double[] array or {@code null}.
949 * @since 2.1
950 */
951 public static double[] addAll(final double[] array1, final double... array2) {
952 if (array1 == null) {
953 return clone(array2);
954 }
955 if (array2 == null) {
956 return clone(array1);
957 }
958 final double[] joinedArray = new double[array1.length + array2.length];
959 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
960 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
961 return joinedArray;
962 }
963
964 /**
965 * Adds all the elements of the given arrays into a new array.
966 * <p>
967 * The new array contains all of the element of {@code array1} followed
968 * by all of the elements {@code array2}. When an array is returned, it is always
969 * a new array.
970 * </p>
971 * <pre>
972 * ArrayUtils.addAll(array1, null) = cloned copy of array1
973 * ArrayUtils.addAll(null, array2) = cloned copy of array2
974 * ArrayUtils.addAll([], []) = []
975 * ArrayUtils.addAll(null, null) = null
976 * </pre>
977 *
978 * @param array1 the first array whose elements are added to the new array.
979 * @param array2 the second array whose elements are added to the new array.
980 * @return The new float[] array or {@code null}.
981 * @since 2.1
982 */
983 public static float[] addAll(final float[] array1, final float... array2) {
984 if (array1 == null) {
985 return clone(array2);
986 }
987 if (array2 == null) {
988 return clone(array1);
989 }
990 final float[] joinedArray = new float[array1.length + array2.length];
991 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
992 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
993 return joinedArray;
994 }
995
996 /**
997 * Adds all the elements of the given arrays into a new array.
998 * <p>
999 * The new array contains all of the element of {@code array1} followed
1000 * by all of the elements {@code array2}. When an array is returned, it is always
1001 * a new array.
1002 * </p>
1003 * <pre>
1004 * ArrayUtils.addAll(array1, null) = cloned copy of array1
1005 * ArrayUtils.addAll(null, array2) = cloned copy of array2
1006 * ArrayUtils.addAll([], []) = []
1007 * ArrayUtils.addAll(null, null) = null
1008 * </pre>
1009 *
1010 * @param array1 the first array whose elements are added to the new array.
1011 * @param array2 the second array whose elements are added to the new array.
1012 * @return The new int[] array or {@code null}.
1013 * @since 2.1
1014 */
1015 public static int[] addAll(final int[] array1, final int... array2) {
1016 if (array1 == null) {
1017 return clone(array2);
1018 }
1019 if (array2 == null) {
1020 return clone(array1);
1021 }
1022 final int[] joinedArray = new int[array1.length + array2.length];
1023 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
1024 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1025 return joinedArray;
1026 }
1027
1028 /**
1029 * Adds all the elements of the given arrays into a new array.
1030 * <p>
1031 * The new array contains all of the element of {@code array1} followed
1032 * by all of the elements {@code array2}. When an array is returned, it is always
1033 * a new array.
1034 * </p>
1035 * <pre>
1036 * ArrayUtils.addAll(array1, null) = cloned copy of array1
1037 * ArrayUtils.addAll(null, array2) = cloned copy of array2
1038 * ArrayUtils.addAll([], []) = []
1039 * ArrayUtils.addAll(null, null) = null
1040 * </pre>
1041 *
1042 * @param array1 the first array whose elements are added to the new array.
1043 * @param array2 the second array whose elements are added to the new array.
1044 * @return The new long[] array or {@code null}.
1045 * @since 2.1
1046 */
1047 public static long[] addAll(final long[] array1, final long... array2) {
1048 if (array1 == null) {
1049 return clone(array2);
1050 }
1051 if (array2 == null) {
1052 return clone(array1);
1053 }
1054 final long[] joinedArray = new long[array1.length + array2.length];
1055 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
1056 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1057 return joinedArray;
1058 }
1059
1060 /**
1061 * Adds all the elements of the given arrays into a new array.
1062 * <p>
1063 * The new array contains all of the element of {@code array1} followed
1064 * by all of the elements {@code array2}. When an array is returned, it is always
1065 * a new array.
1066 * </p>
1067 * <pre>
1068 * ArrayUtils.addAll(array1, null) = cloned copy of array1
1069 * ArrayUtils.addAll(null, array2) = cloned copy of array2
1070 * ArrayUtils.addAll([], []) = []
1071 * ArrayUtils.addAll(null, null) = null
1072 * </pre>
1073 *
1074 * @param array1 the first array whose elements are added to the new array.
1075 * @param array2 the second array whose elements are added to the new array.
1076 * @return The new short[] array or {@code null}.
1077 * @since 2.1
1078 */
1079 public static short[] addAll(final short[] array1, final short... array2) {
1080 if (array1 == null) {
1081 return clone(array2);
1082 }
1083 if (array2 == null) {
1084 return clone(array1);
1085 }
1086 final short[] joinedArray = new short[array1.length + array2.length];
1087 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
1088 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1089 return joinedArray;
1090 }
1091
1092 /**
1093 * Adds all the elements of the given arrays into a new array.
1094 * <p>
1095 * The new array contains all of the element of {@code array1} followed
1096 * by all of the elements {@code array2}. When an array is returned, it is always
1097 * a new array.
1098 * </p>
1099 * <pre>
1100 * ArrayUtils.addAll(null, null) = null
1101 * ArrayUtils.addAll(array1, null) = cloned copy of array1
1102 * ArrayUtils.addAll(null, array2) = cloned copy of array2
1103 * ArrayUtils.addAll([], []) = []
1104 * ArrayUtils.addAll(null, null) = null
1105 * ArrayUtils.addAll([null], [null]) = [null, null]
1106 * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
1107 * </pre>
1108 *
1109 * @param <T> the component type of the array
1110 * @param array1 the first array whose elements are added to the new array, may be {@code null}
1111 * @param array2 the second array whose elements are added to the new array, may be {@code null}
1112 * @return The new array, {@code null} if both arrays are {@code null}.
1113 * The type of the new array is the type of the first array,
1114 * unless the first array is null, in which case the type is the same as the second array.
1115 * @throws IllegalArgumentException if the array types are incompatible
1116 * @since 2.1
1117 */
1118 public static <T> T[] addAll(final T[] array1, @SuppressWarnings("unchecked") final T... array2) {
1119 if (array1 == null) {
1120 return clone(array2);
1121 }
1122 if (array2 == null) {
1123 return clone(array1);
1124 }
1125 final Class<T> type1 = getComponentType(array1);
1126 final T[] joinedArray = arraycopy(array1, 0, 0, array1.length, () -> newInstance(type1, array1.length + array2.length));
1127 try {
1128 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1129 } catch (final ArrayStoreException ase) {
1130 // Check if problem was due to incompatible types
1131 /*
1132 * We do this here, rather than before the copy because: - it would be a wasted check most of the time - safer, in case check turns out to be too
1133 * strict
1134 */
1135 final Class<?> type2 = array2.getClass().getComponentType();
1136 if (!type1.isAssignableFrom(type2)) {
1137 throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of " + type1.getName(), ase);
1138 }
1139 throw ase; // No, so rethrow original
1140 }
1141 return joinedArray;
1142 }
1143
1144 /**
1145 * Copies the given array and adds the given element at the beginning of the new array.
1146 * <p>
1147 * The new array contains the same elements of the input array plus the given element in the first position. The
1148 * component type of the new array is the same as that of the input array.
1149 * </p>
1150 * <p>
1151 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1152 * element.
1153 * </p>
1154 * <pre>
1155 * ArrayUtils.addFirst(null, true) = [true]
1156 * ArrayUtils.addFirst([true], false) = [false, true]
1157 * ArrayUtils.addFirst([true, false], true) = [true, true, false]
1158 * </pre>
1159 *
1160 * @param array the array to "add" the element to, may be {@code null}.
1161 * @param element the object to add.
1162 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1163 * the input array (unless null), in which case it will have the same type as the element.
1164 * @since 3.10
1165 */
1166 public static boolean[] addFirst(final boolean[] array, final boolean element) {
1167 return array == null ? add(array, element) : insert(0, array, element);
1168 }
1169
1170 /**
1171 * Copies the given array and adds the given element at the beginning of the new array.
1172 * <p>
1173 * The new array contains the same elements of the input array plus the given element in the first position. The
1174 * component type of the new array is the same as that of the input array.
1175 * </p>
1176 * <p>
1177 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1178 * element.
1179 * </p>
1180 * <pre>
1181 * ArrayUtils.addFirst(null, 1) = [1]
1182 * ArrayUtils.addFirst([1], 0) = [0, 1]
1183 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1184 * </pre>
1185 *
1186 * @param array the array to "add" the element to, may be {@code null}.
1187 * @param element the object to add.
1188 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1189 * the input array (unless null), in which case it will have the same type as the element.
1190 * @since 3.10
1191 */
1192 public static byte[] addFirst(final byte[] array, final byte element) {
1193 return array == null ? add(array, element) : insert(0, array, element);
1194 }
1195
1196 /**
1197 * Copies the given array and adds the given element at the beginning of the new array.
1198 * <p>
1199 * The new array contains the same elements of the input array plus the given element in the first position. The
1200 * component type of the new array is the same as that of the input array.
1201 * </p>
1202 * <p>
1203 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1204 * element.
1205 * </p>
1206 * <pre>
1207 * ArrayUtils.addFirst(null, '1') = ['1']
1208 * ArrayUtils.addFirst(['1'], '0') = ['0', '1']
1209 * ArrayUtils.addFirst(['1', '0'], '1') = ['1', '1', '0']
1210 * </pre>
1211 *
1212 * @param array the array to "add" the element to, may be {@code null}.
1213 * @param element the object to add.
1214 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1215 * the input array (unless null), in which case it will have the same type as the element.
1216 * @since 3.10
1217 */
1218 public static char[] addFirst(final char[] array, final char element) {
1219 return array == null ? add(array, element) : insert(0, array, element);
1220 }
1221
1222 /**
1223 * Copies the given array and adds the given element at the beginning of the new array.
1224 * <p>
1225 * The new array contains the same elements of the input array plus the given element in the first position. The
1226 * component type of the new array is the same as that of the input array.
1227 * </p>
1228 * <p>
1229 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1230 * element.
1231 * </p>
1232 * <pre>
1233 * ArrayUtils.addFirst(null, 1) = [1]
1234 * ArrayUtils.addFirst([1], 0) = [0, 1]
1235 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1236 * </pre>
1237 *
1238 * @param array the array to "add" the element to, may be {@code null}.
1239 * @param element the object to add.
1240 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1241 * the input array (unless null), in which case it will have the same type as the element.
1242 * @since 3.10
1243 */
1244 public static double[] addFirst(final double[] array, final double element) {
1245 return array == null ? add(array, element) : insert(0, array, element);
1246 }
1247
1248 /**
1249 * Copies the given array and adds the given element at the beginning of the new array.
1250 * <p>
1251 * The new array contains the same elements of the input array plus the given element in the first position. The
1252 * component type of the new array is the same as that of the input array.
1253 * </p>
1254 * <p>
1255 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1256 * element.
1257 * </p>
1258 * <pre>
1259 * ArrayUtils.addFirst(null, 1) = [1]
1260 * ArrayUtils.addFirst([1], 0) = [0, 1]
1261 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1262 * </pre>
1263 *
1264 * @param array the array to "add" the element to, may be {@code null}.
1265 * @param element the object to add.
1266 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1267 * the input array (unless null), in which case it will have the same type as the element.
1268 * @since 3.10
1269 */
1270 public static float[] addFirst(final float[] array, final float element) {
1271 return array == null ? add(array, element) : insert(0, array, element);
1272 }
1273
1274 /**
1275 * Copies the given array and adds the given element at the beginning of the new array.
1276 * <p>
1277 * The new array contains the same elements of the input array plus the given element in the first position. The
1278 * component type of the new array is the same as that of the input array.
1279 * </p>
1280 * <p>
1281 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1282 * element.
1283 * </p>
1284 * <pre>
1285 * ArrayUtils.addFirst(null, 1) = [1]
1286 * ArrayUtils.addFirst([1], 0) = [0, 1]
1287 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1288 * </pre>
1289 *
1290 * @param array the array to "add" the element to, may be {@code null}.
1291 * @param element the object to add.
1292 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1293 * the input array (unless null), in which case it will have the same type as the element.
1294 * @since 3.10
1295 */
1296 public static int[] addFirst(final int[] array, final int element) {
1297 return array == null ? add(array, element) : insert(0, array, element);
1298 }
1299
1300 /**
1301 * Copies the given array and adds the given element at the beginning of the new array.
1302 * <p>
1303 * The new array contains the same elements of the input array plus the given element in the first position. The
1304 * component type of the new array is the same as that of the input array.
1305 * </p>
1306 * <p>
1307 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1308 * element.
1309 * </p>
1310 * <pre>
1311 * ArrayUtils.addFirst(null, 1) = [1]
1312 * ArrayUtils.addFirst([1], 0) = [0, 1]
1313 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1314 * </pre>
1315 *
1316 * @param array the array to "add" the element to, may be {@code null}.
1317 * @param element the object to add.
1318 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1319 * the input array (unless null), in which case it will have the same type as the element.
1320 * @since 3.10
1321 */
1322 public static long[] addFirst(final long[] array, final long element) {
1323 return array == null ? add(array, element) : insert(0, array, element);
1324 }
1325
1326 /**
1327 * Copies the given array and adds the given element at the beginning of the new array.
1328 * <p>
1329 * The new array contains the same elements of the input array plus the given element in the first position. The
1330 * component type of the new array is the same as that of the input array.
1331 * </p>
1332 * <p>
1333 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1334 * element.
1335 * </p>
1336 * <pre>
1337 * ArrayUtils.addFirst(null, 1) = [1]
1338 * ArrayUtils.addFirst([1], 0) = [0, 1]
1339 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1340 * </pre>
1341 *
1342 * @param array the array to "add" the element to, may be {@code null}.
1343 * @param element the object to add.
1344 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1345 * the input array (unless null), in which case it will have the same type as the element.
1346 * @since 3.10
1347 */
1348 public static short[] addFirst(final short[] array, final short element) {
1349 return array == null ? add(array, element) : insert(0, array, element);
1350 }
1351
1352 /**
1353 * Copies the given array and adds the given element at the beginning of the new array.
1354 * <p>
1355 * The new array contains the same elements of the input array plus the given element in the first position. The
1356 * component type of the new array is the same as that of the input array.
1357 * </p>
1358 * <p>
1359 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1360 * element, unless the element itself is null, in which case the return type is Object[]
1361 * </p>
1362 * <pre>
1363 * ArrayUtils.addFirst(null, null) = IllegalArgumentException
1364 * ArrayUtils.addFirst(null, "a") = ["a"]
1365 * ArrayUtils.addFirst(["a"], null) = [null, "a"]
1366 * ArrayUtils.addFirst(["a"], "b") = ["b", "a"]
1367 * ArrayUtils.addFirst(["a", "b"], "c") = ["c", "a", "b"]
1368 * </pre>
1369 *
1370 * @param <T> the component type of the array
1371 * @param array the array to "add" the element to, may be {@code null}
1372 * @param element the object to add, may be {@code null}
1373 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1374 * the input array (unless null), in which case it will have the same type as the element. If both are null,
1375 * an IllegalArgumentException is thrown
1376 * @throws IllegalArgumentException if both arguments are null
1377 * @since 3.10
1378 */
1379 public static <T> T[] addFirst(final T[] array, final T element) {
1380 return array == null ? add(array, element) : insert(0, array, element);
1381 }
1382
1383 /**
1384 * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the destination array.
1385 *
1386 * @param <T> the type.
1387 * @param source the source array.
1388 * @param sourcePos starting position in the source array.
1389 * @param destPos starting position in the destination data.
1390 * @param length the number of array elements to be copied.
1391 * @param allocator allocates the array to populate and return.
1392 * @return dest
1393 * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds.
1394 * @throws ArrayStoreException if an element in the {@code src} array could not be stored into the {@code dest} array because of a type
1395 * mismatch.
1396 * @throws NullPointerException if either {@code src} or {@code dest} is {@code null}.
1397 * @since 3.15.0
1398 */
1399 public static <T> T arraycopy(final T source, final int sourcePos, final int destPos, final int length, final Function<Integer, T> allocator) {
1400 return arraycopy(source, sourcePos, allocator.apply(length), destPos, length);
1401 }
1402
1403 /**
1404 * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the destination array.
1405 *
1406 * @param <T> the type.
1407 * @param source the source array.
1408 * @param sourcePos starting position in the source array.
1409 * @param destPos starting position in the destination data.
1410 * @param length the number of array elements to be copied.
1411 * @param allocator allocates the array to populate and return.
1412 * @return dest
1413 * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds.
1414 * @throws ArrayStoreException if an element in the {@code src} array could not be stored into the {@code dest} array because of a type
1415 * mismatch.
1416 * @throws NullPointerException if either {@code src} or {@code dest} is {@code null}.
1417 * @since 3.15.0
1418 */
1419 public static <T> T arraycopy(final T source, final int sourcePos, final int destPos, final int length, final Supplier<T> allocator) {
1420 return arraycopy(source, sourcePos, allocator.get(), destPos, length);
1421 }
1422
1423 /**
1424 * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the destination array.
1425 *
1426 * @param <T> the type
1427 * @param source the source array.
1428 * @param sourcePos starting position in the source array.
1429 * @param dest the destination array.
1430 * @param destPos starting position in the destination data.
1431 * @param length the number of array elements to be copied.
1432 * @return dest
1433 * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds.
1434 * @throws ArrayStoreException if an element in the {@code src} array could not be stored into the {@code dest} array because of a type
1435 * mismatch.
1436 * @throws NullPointerException if either {@code src} or {@code dest} is {@code null}.
1437 * @since 3.15.0
1438 */
1439 public static <T> T arraycopy(final T source, final int sourcePos, final T dest, final int destPos, final int length) {
1440 System.arraycopy(source, sourcePos, dest, destPos, length);
1441 return dest;
1442 }
1443
1444 /**
1445 * Clones an array or returns {@code null}.
1446 * <p>
1447 * This method returns {@code null} for a {@code null} input array.
1448 * </p>
1449 *
1450 * @param array the array to clone, may be {@code null}
1451 * @return the cloned array, {@code null} if {@code null} input
1452 */
1453 public static boolean[] clone(final boolean[] array) {
1454 return array != null ? array.clone() : null;
1455 }
1456
1457 /**
1458 * Clones an array or returns {@code null}.
1459 * <p>
1460 * This method returns {@code null} for a {@code null} input array.
1461 * </p>
1462 *
1463 * @param array the array to clone, may be {@code null}
1464 * @return the cloned array, {@code null} if {@code null} input
1465 */
1466 public static byte[] clone(final byte[] array) {
1467 return array != null ? array.clone() : null;
1468 }
1469
1470 /**
1471 * Clones an array or returns {@code null}.
1472 * <p>
1473 * This method returns {@code null} for a {@code null} input array.
1474 * </p>
1475 *
1476 * @param array the array to clone, may be {@code null}
1477 * @return the cloned array, {@code null} if {@code null} input
1478 */
1479 public static char[] clone(final char[] array) {
1480 return array != null ? array.clone() : null;
1481 }
1482
1483 /**
1484 * Clones an array or returns {@code null}.
1485 * <p>
1486 * This method returns {@code null} for a {@code null} input array.
1487 * </p>
1488 *
1489 * @param array the array to clone, may be {@code null}
1490 * @return the cloned array, {@code null} if {@code null} input
1491 */
1492 public static double[] clone(final double[] array) {
1493 return array != null ? array.clone() : null;
1494 }
1495
1496 /**
1497 * Clones an array or returns {@code null}.
1498 * <p>
1499 * This method returns {@code null} for a {@code null} input array.
1500 * </p>
1501 *
1502 * @param array the array to clone, may be {@code null}
1503 * @return the cloned array, {@code null} if {@code null} input
1504 */
1505 public static float[] clone(final float[] array) {
1506 return array != null ? array.clone() : null;
1507 }
1508
1509 /**
1510 * Clones an array or returns {@code null}.
1511 * <p>
1512 * This method returns {@code null} for a {@code null} input array.
1513 * </p>
1514 *
1515 * @param array the array to clone, may be {@code null}
1516 * @return the cloned array, {@code null} if {@code null} input
1517 */
1518 public static int[] clone(final int[] array) {
1519 return array != null ? array.clone() : null;
1520 }
1521
1522 /**
1523 * Clones an array or returns {@code null}.
1524 * <p>
1525 * This method returns {@code null} for a {@code null} input array.
1526 * </p>
1527 *
1528 * @param array the array to clone, may be {@code null}
1529 * @return the cloned array, {@code null} if {@code null} input
1530 */
1531 public static long[] clone(final long[] array) {
1532 return array != null ? array.clone() : null;
1533 }
1534
1535 /**
1536 * Clones an array or returns {@code null}.
1537 * <p>
1538 * This method returns {@code null} for a {@code null} input array.
1539 * </p>
1540 *
1541 * @param array the array to clone, may be {@code null}
1542 * @return the cloned array, {@code null} if {@code null} input
1543 */
1544 public static short[] clone(final short[] array) {
1545 return array != null ? array.clone() : null;
1546 }
1547
1548 /**
1549 * Shallow clones an array or returns {@code null}.
1550 * <p>
1551 * The objects in the array are not cloned, thus there is no special handling for multi-dimensional arrays.
1552 * </p>
1553 * <p>
1554 * This method returns {@code null} for a {@code null} input array.
1555 * </p>
1556 *
1557 * @param <T> the component type of the array
1558 * @param array the array to shallow clone, may be {@code null}
1559 * @return the cloned array, {@code null} if {@code null} input
1560 */
1561 public static <T> T[] clone(final T[] array) {
1562 return array != null ? array.clone() : null;
1563 }
1564
1565 /**
1566 * Checks if the value is in the given array.
1567 * <p>
1568 * The method returns {@code false} if a {@code null} array is passed in.
1569 * </p>
1570 *
1571 * @param array the array to search
1572 * @param valueToFind the value to find
1573 * @return {@code true} if the array contains the object
1574 */
1575 public static boolean contains(final boolean[] array, final boolean valueToFind) {
1576 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1577 }
1578
1579 /**
1580 * Checks if the value is in the given array.
1581 * <p>
1582 * The method returns {@code false} if a {@code null} array is passed in.
1583 * </p>
1584 * <p>
1585 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1586 * {@link Arrays#sort(byte[])} and {@link Arrays#binarySearch(byte[], byte)}.
1587 * </p>
1588 *
1589 * @param array the array to search
1590 * @param valueToFind the value to find
1591 * @return {@code true} if the array contains the object
1592 */
1593 public static boolean contains(final byte[] array, final byte valueToFind) {
1594 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1595 }
1596
1597 /**
1598 * Checks if the value is in the given array.
1599 * <p>
1600 * The method returns {@code false} if a {@code null} array is passed in.
1601 * </p>
1602 * <p>
1603 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1604 * {@link Arrays#sort(char[])} and {@link Arrays#binarySearch(char[], char)}.
1605 * </p>
1606 *
1607 * @param array the array to search
1608 * @param valueToFind the value to find
1609 * @return {@code true} if the array contains the object
1610 * @since 2.1
1611 */
1612 public static boolean contains(final char[] array, final char valueToFind) {
1613 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1614 }
1615
1616 /**
1617 * Checks if the value is in the given array.
1618 * <p>
1619 * The method returns {@code false} if a {@code null} array is passed in.
1620 * </p>
1621 * <p>
1622 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1623 * {@link Arrays#sort(double[])} and {@link Arrays#binarySearch(double[], double)}.
1624 * </p>
1625 *
1626 * @param array the array to search
1627 * @param valueToFind the value to find
1628 * @return {@code true} if the array contains the object
1629 */
1630 public static boolean contains(final double[] array, final double valueToFind) {
1631 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1632 }
1633
1634 /**
1635 * Checks if a value falling within the given tolerance is in the
1636 * given array. If the array contains a value within the inclusive range
1637 * defined by (value - tolerance) to (value + tolerance).
1638 * <p>
1639 * The method returns {@code false} if a {@code null} array
1640 * is passed in.
1641 * </p>
1642 * <p>
1643 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1644 * {@link Arrays#sort(double[])} and {@link Arrays#binarySearch(double[], double)}.
1645 * </p>
1646 *
1647 * @param array the array to search
1648 * @param valueToFind the value to find
1649 * @param tolerance the array contains the tolerance of the search
1650 * @return true if value falling within tolerance is in array
1651 */
1652 public static boolean contains(final double[] array, final double valueToFind, final double tolerance) {
1653 return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
1654 }
1655
1656 /**
1657 * Checks if the value is in the given array.
1658 * <p>
1659 * The method returns {@code false} if a {@code null} array is passed in.
1660 * </p>
1661 * <p>
1662 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1663 * {@link Arrays#sort(float[])} and {@link Arrays#binarySearch(float[], float)}.
1664 * </p>
1665 *
1666 * @param array the array to search
1667 * @param valueToFind the value to find
1668 * @return {@code true} if the array contains the object
1669 */
1670 public static boolean contains(final float[] array, final float valueToFind) {
1671 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1672 }
1673
1674 /**
1675 * Checks if the value is in the given array.
1676 * <p>
1677 * The method returns {@code false} if a {@code null} array is passed in.
1678 * </p>
1679 * <p>
1680 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1681 * {@link Arrays#sort(int[])} and {@link Arrays#binarySearch(int[], int)}.
1682 * </p>
1683 *
1684 * @param array the array to search
1685 * @param valueToFind the value to find
1686 * @return {@code true} if the array contains the object
1687 */
1688 public static boolean contains(final int[] array, final int valueToFind) {
1689 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1690 }
1691
1692 /**
1693 * Checks if the value is in the given array.
1694 * <p>
1695 * The method returns {@code false} if a {@code null} array is passed in.
1696 * </p>
1697 * <p>
1698 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1699 * {@link Arrays#sort(long[])} and {@link Arrays#binarySearch(long[], long)}.
1700 * </p>
1701 *
1702 * @param array the array to search
1703 * @param valueToFind the value to find
1704 * @return {@code true} if the array contains the object
1705 */
1706 public static boolean contains(final long[] array, final long valueToFind) {
1707 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1708 }
1709
1710 /**
1711 * Checks if the object is in the given array.
1712 * <p>
1713 * The method returns {@code false} if a {@code null} array is passed in.
1714 * </p>
1715 * <p>
1716 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1717 * {@link Arrays#sort(Object[], Comparator)} and {@link Arrays#binarySearch(Object[], Object)}.
1718 * </p>
1719 *
1720 * @param array the array to search, may be {@code null}.
1721 * @param objectToFind the object to find, may be {@code null}.
1722 * @return {@code true} if the array contains the object
1723 */
1724 public static boolean contains(final Object[] array, final Object objectToFind) {
1725 return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
1726 }
1727
1728 /**
1729 * Checks if the value is in the given array.
1730 * <p>
1731 * The method returns {@code false} if a {@code null} array is passed in.
1732 * </p>
1733 * <p>
1734 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1735 * {@link Arrays#sort(short[])} and {@link Arrays#binarySearch(short[], short)}.
1736 * </p>
1737 *
1738 * @param array the array to search
1739 * @param valueToFind the value to find
1740 * @return {@code true} if the array contains the object
1741 */
1742 public static boolean contains(final short[] array, final short valueToFind) {
1743 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1744 }
1745
1746 /**
1747 * Checks if any of the ints are in the given array.
1748 * <p>
1749 * The method returns {@code false} if a {@code null} array is passed in.
1750 * </p>
1751 * <p>
1752 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1753 * {@link Arrays#sort(int[])} and {@link Arrays#binarySearch(int[], int)}.
1754 * </p>
1755 *
1756 * @param array the array to search
1757 * @param objectsToFind any of the ints to find
1758 * @return {@code true} if the array contains any of the ints
1759 * @since 3.18.0
1760 */
1761 public static boolean containsAny(final int[] array, final int... objectsToFind) {
1762 return IntStreams.of(objectsToFind).anyMatch(e -> contains(array, e));
1763 }
1764
1765 /**
1766 * Checks if any of the objects are in the given array.
1767 * <p>
1768 * The method returns {@code false} if a {@code null} array is passed in.
1769 * </p>
1770 * <p>
1771 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1772 * {@link Arrays#sort(Object[], Comparator)} and {@link Arrays#binarySearch(Object[], Object)}.
1773 * </p>
1774 *
1775 * @param array the array to search, may be {@code null}.
1776 * @param objectsToFind any of the objects to find, may be {@code null}.
1777 * @return {@code true} if the array contains any of the objects
1778 * @since 3.13.0
1779 */
1780 public static boolean containsAny(final Object[] array, final Object... objectsToFind) {
1781 return Streams.of(objectsToFind).anyMatch(e -> contains(array, e));
1782 }
1783
1784 /**
1785 * Returns a copy of the given array of size 1 greater than the argument.
1786 * The last value of the array is left to the default value.
1787 *
1788 * @param array The array to copy, must not be {@code null}.
1789 * @param newArrayComponentType If {@code array} is {@code null}, create a
1790 * size 1 array of this type.
1791 * @return A new copy of the array of size 1 greater than the input.
1792 */
1793 private static Object copyArrayGrow1(final Object array, final Class<?> newArrayComponentType) {
1794 if (array != null) {
1795 final int arrayLength = Array.getLength(array);
1796 final Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
1797 System.arraycopy(array, 0, newArray, 0, arrayLength);
1798 return newArray;
1799 }
1800 return Array.newInstance(newArrayComponentType, 1);
1801 }
1802
1803 /**
1804 * Gets the nTh element of an array or null if the index is out of bounds or the array is null.
1805 *
1806 * @param <T> The type of array elements.
1807 * @param array The array to index.
1808 * @param index The index
1809 * @return the nTh element of an array or null if the index is out of bounds or the array is null.
1810 * @since 3.11
1811 */
1812 public static <T> T get(final T[] array, final int index) {
1813 return get(array, index, null);
1814 }
1815
1816 /**
1817 * Gets the nTh element of an array or a default value if the index is out of bounds.
1818 *
1819 * @param <T> The type of array elements.
1820 * @param array The array to index.
1821 * @param index The index
1822 * @param defaultValue The return value of the given index is out of bounds.
1823 * @return the nTh element of an array or a default value if the index is out of bounds.
1824 * @since 3.11
1825 */
1826 public static <T> T get(final T[] array, final int index, final T defaultValue) {
1827 return isArrayIndexValid(array, index) ? array[index] : defaultValue;
1828 }
1829
1830 /**
1831 * Gets an array's component type.
1832 *
1833 * @param <T> The array type.
1834 * @param array The array.
1835 * @return The component type.
1836 * @since 3.13.0
1837 */
1838 public static <T> Class<T> getComponentType(final T[] array) {
1839 return ClassUtils.getComponentType(ObjectUtils.getClass(array));
1840 }
1841
1842 /**
1843 * Gets the length of the specified array.
1844 * This method can deal with {@link Object} arrays and with primitive arrays.
1845 * <p>
1846 * If the input array is {@code null}, {@code 0} is returned.
1847 * </p>
1848 * <pre>
1849 * ArrayUtils.getLength(null) = 0
1850 * ArrayUtils.getLength([]) = 0
1851 * ArrayUtils.getLength([null]) = 1
1852 * ArrayUtils.getLength([true, false]) = 2
1853 * ArrayUtils.getLength([1, 2, 3]) = 3
1854 * ArrayUtils.getLength(["a", "b", "c"]) = 3
1855 * </pre>
1856 *
1857 * @param array the array to retrieve the length from, may be {@code null}.
1858 * @return The length of the array, or {@code 0} if the array is {@code null}
1859 * @throws IllegalArgumentException if the object argument is not an array.
1860 * @since 2.1
1861 */
1862 public static int getLength(final Object array) {
1863 return array != null ? Array.getLength(array) : 0;
1864 }
1865
1866 /**
1867 * Gets a hash code for an array handling multidimensional arrays correctly.
1868 * <p>
1869 * Multi-dimensional primitive arrays are also handled correctly by this method.
1870 * </p>
1871 *
1872 * @param array the array to get a hash code for, {@code null} returns zero
1873 * @return a hash code for the array
1874 */
1875 public static int hashCode(final Object array) {
1876 return new HashCodeBuilder().append(array).toHashCode();
1877 }
1878
1879 static <K> void increment(final Map<K, MutableInt> occurrences, final K boxed) {
1880 occurrences.computeIfAbsent(boxed, k -> new MutableInt()).increment();
1881 }
1882
1883 /**
1884 * Finds the indices of the given value in the array.
1885 * <p>
1886 * This method returns an empty BitSet for a {@code null} input array.
1887 * </p>
1888 *
1889 * @param array the array to search for the object, may be {@code null}
1890 * @param valueToFind the value to find
1891 * @return a BitSet of all the indices of the value within the array,
1892 * an empty BitSet if not found or {@code null} array input
1893 * @since 3.10
1894 */
1895 public static BitSet indexesOf(final boolean[] array, final boolean valueToFind) {
1896 return indexesOf(array, valueToFind, 0);
1897 }
1898
1899 /**
1900 * Finds the indices of the given value in the array starting at the given index.
1901 * <p>
1902 * This method returns an empty BitSet for a {@code null} input array.
1903 * </p>
1904 * <p>
1905 * A negative startIndex is treated as zero. A startIndex larger than the array
1906 * length will return an empty BitSet ({@code -1}).
1907 * </p>
1908 *
1909 * @param array the array to search for the object, may be {@code null}
1910 * @param valueToFind the value to find
1911 * @param startIndex the index to start searching at
1912 * @return a BitSet of all the indices of the value within the array,
1913 * an empty BitSet if not found or {@code null}
1914 * array input
1915 * @since 3.10
1916 */
1917 public static BitSet indexesOf(final boolean[] array, final boolean valueToFind, int startIndex) {
1918 final BitSet bitSet = new BitSet();
1919 if (array == null) {
1920 return bitSet;
1921 }
1922 while (startIndex < array.length) {
1923 startIndex = indexOf(array, valueToFind, startIndex);
1924 if (startIndex == INDEX_NOT_FOUND) {
1925 break;
1926 }
1927 bitSet.set(startIndex);
1928 ++startIndex;
1929 }
1930 return bitSet;
1931 }
1932
1933 /**
1934 * Finds the indices of the given value in the array.
1935 *
1936 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
1937 *
1938 * @param array the array to search for the object, may be {@code null}
1939 * @param valueToFind the value to find
1940 * @return a BitSet of all the indices of the value within the array,
1941 * an empty BitSet if not found or {@code null} array input
1942 * @since 3.10
1943 */
1944 public static BitSet indexesOf(final byte[] array, final byte valueToFind) {
1945 return indexesOf(array, valueToFind, 0);
1946 }
1947
1948 /**
1949 * Finds the indices of the given value in the array starting at the given index.
1950 *
1951 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
1952 *
1953 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1954 * length will return an empty BitSet.</p>
1955 *
1956 * @param array the array to search for the object, may be {@code null}
1957 * @param valueToFind the value to find
1958 * @param startIndex the index to start searching at
1959 * @return a BitSet of all the indices of the value within the array,
1960 * an empty BitSet if not found or {@code null} array input
1961 * @since 3.10
1962 */
1963 public static BitSet indexesOf(final byte[] array, final byte valueToFind, int startIndex) {
1964 final BitSet bitSet = new BitSet();
1965 if (array == null) {
1966 return bitSet;
1967 }
1968 while (startIndex < array.length) {
1969 startIndex = indexOf(array, valueToFind, startIndex);
1970 if (startIndex == INDEX_NOT_FOUND) {
1971 break;
1972 }
1973 bitSet.set(startIndex);
1974 ++startIndex;
1975 }
1976
1977 return bitSet;
1978 }
1979
1980 /**
1981 * Finds the indices of the given value in the array.
1982 *
1983 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
1984 *
1985 * @param array the array to search for the object, may be {@code null}
1986 * @param valueToFind the value to find
1987 * @return a BitSet of all the indices of the value within the array,
1988 * an empty BitSet if not found or {@code null} array input
1989 * @since 3.10
1990 */
1991 public static BitSet indexesOf(final char[] array, final char valueToFind) {
1992 return indexesOf(array, valueToFind, 0);
1993 }
1994
1995 /**
1996 * Finds the indices of the given value in the array starting at the given index.
1997 *
1998 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
1999 *
2000 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2001 * length will return an empty BitSet.</p>
2002 *
2003 * @param array the array to search for the object, may be {@code null}
2004 * @param valueToFind the value to find
2005 * @param startIndex the index to start searching at
2006 * @return a BitSet of all the indices of the value within the array,
2007 * an empty BitSet if not found or {@code null} array input
2008 * @since 3.10
2009 */
2010 public static BitSet indexesOf(final char[] array, final char valueToFind, int startIndex) {
2011 final BitSet bitSet = new BitSet();
2012 if (array == null) {
2013 return bitSet;
2014 }
2015 while (startIndex < array.length) {
2016 startIndex = indexOf(array, valueToFind, startIndex);
2017 if (startIndex == INDEX_NOT_FOUND) {
2018 break;
2019 }
2020 bitSet.set(startIndex);
2021 ++startIndex;
2022 }
2023 return bitSet;
2024 }
2025
2026 /**
2027 * Finds the indices of the given value in the array.
2028 *
2029 * <p>This method returns empty BitSet for a {@code null} input array.</p>
2030 *
2031 * @param array the array to search for the object, may be {@code null}
2032 * @param valueToFind the value to find
2033 * @return a BitSet of all the indices of the value within the array,
2034 * an empty BitSet if not found or {@code null} array input
2035 * @since 3.10
2036 */
2037 public static BitSet indexesOf(final double[] array, final double valueToFind) {
2038 return indexesOf(array, valueToFind, 0);
2039 }
2040
2041 /**
2042 * Finds the indices of the given value within a given tolerance in the array.
2043 *
2044 * <p>
2045 * This method will return all the indices of the value which fall between the region
2046 * defined by valueToFind - tolerance and valueToFind + tolerance, each time between the nearest integers.
2047 * </p>
2048 *
2049 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2050 *
2051 * @param array the array to search for the object, may be {@code null}
2052 * @param valueToFind the value to find
2053 * @param tolerance tolerance of the search
2054 * @return a BitSet of all the indices of the value within the array,
2055 * an empty BitSet if not found or {@code null} array input
2056 * @since 3.10
2057 */
2058 public static BitSet indexesOf(final double[] array, final double valueToFind, final double tolerance) {
2059 return indexesOf(array, valueToFind, 0, tolerance);
2060 }
2061
2062 /**
2063 * Finds the indices of the given value in the array starting at the given index.
2064 *
2065 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2066 *
2067 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2068 * length will return an empty BitSet.</p>
2069 *
2070 * @param array the array to search for the object, may be {@code null}
2071 * @param valueToFind the value to find
2072 * @param startIndex the index to start searching at
2073 * @return a BitSet of the indices of the value within the array,
2074 * an empty BitSet if not found or {@code null} array input
2075 * @since 3.10
2076 */
2077 public static BitSet indexesOf(final double[] array, final double valueToFind, int startIndex) {
2078 final BitSet bitSet = new BitSet();
2079 if (array == null) {
2080 return bitSet;
2081 }
2082 while (startIndex < array.length) {
2083 startIndex = indexOf(array, valueToFind, startIndex);
2084 if (startIndex == INDEX_NOT_FOUND) {
2085 break;
2086 }
2087 bitSet.set(startIndex);
2088 ++startIndex;
2089 }
2090 return bitSet;
2091 }
2092
2093 /**
2094 * Finds the indices of the given value in the array starting at the given index.
2095 *
2096 * <p>
2097 * This method will return the indices of the values which fall between the region
2098 * defined by valueToFind - tolerance and valueToFind + tolerance, between the nearest integers.
2099 * </p>
2100 *
2101 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2102 *
2103 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2104 * length will return an empty BitSet.</p>
2105 *
2106 * @param array the array to search for the object, may be {@code null}
2107 * @param valueToFind the value to find
2108 * @param startIndex the index to start searching at
2109 * @param tolerance tolerance of the search
2110 * @return a BitSet of the indices of the value within the array,
2111 * an empty BitSet if not found or {@code null} array input
2112 * @since 3.10
2113 */
2114 public static BitSet indexesOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
2115 final BitSet bitSet = new BitSet();
2116 if (array == null) {
2117 return bitSet;
2118 }
2119 while (startIndex < array.length) {
2120 startIndex = indexOf(array, valueToFind, startIndex, tolerance);
2121 if (startIndex == INDEX_NOT_FOUND) {
2122 break;
2123 }
2124 bitSet.set(startIndex);
2125 ++startIndex;
2126 }
2127 return bitSet;
2128 }
2129
2130 /**
2131 * Finds the indices of the given value in the array.
2132 *
2133 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2134 *
2135 * @param array the array to search for the object, may be {@code null}
2136 * @param valueToFind the value to find
2137 * @return a BitSet of all the indices of the value within the array,
2138 * an empty BitSet if not found or {@code null} array input
2139 * @since 3.10
2140 */
2141 public static BitSet indexesOf(final float[] array, final float valueToFind) {
2142 return indexesOf(array, valueToFind, 0);
2143 }
2144
2145 /**
2146 * Finds the indices of the given value in the array starting at the given index.
2147 *
2148 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2149 *
2150 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2151 * length will return empty BitSet.</p>
2152 *
2153 * @param array the array to search for the object, may be {@code null}
2154 * @param valueToFind the value to find
2155 * @param startIndex the index to start searching at
2156 * @return a BitSet of all the indices of the value within the array,
2157 * an empty BitSet if not found or {@code null} array input
2158 * @since 3.10
2159 */
2160 public static BitSet indexesOf(final float[] array, final float valueToFind, int startIndex) {
2161 final BitSet bitSet = new BitSet();
2162 if (array == null) {
2163 return bitSet;
2164 }
2165 while (startIndex < array.length) {
2166 startIndex = indexOf(array, valueToFind, startIndex);
2167 if (startIndex == INDEX_NOT_FOUND) {
2168 break;
2169 }
2170 bitSet.set(startIndex);
2171 ++startIndex;
2172 }
2173 return bitSet;
2174 }
2175
2176 /**
2177 * Finds the indices of the given value in the array.
2178 *
2179 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2180 *
2181 * @param array the array to search for the object, may be {@code null}
2182 * @param valueToFind the value to find
2183 * @return a BitSet of all the indices of the value within the array,
2184 * an empty BitSet if not found or {@code null} array input
2185 * @since 3.10
2186 */
2187 public static BitSet indexesOf(final int[] array, final int valueToFind) {
2188 return indexesOf(array, valueToFind, 0);
2189 }
2190
2191 /**
2192 * Finds the indices of the given value in the array starting at the given index.
2193 *
2194 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2195 *
2196 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2197 * length will return an empty BitSet.</p>
2198 *
2199 * @param array the array to search for the object, may be {@code null}
2200 * @param valueToFind the value to find
2201 * @param startIndex the index to start searching at
2202 * @return a BitSet of all the indices of the value within the array,
2203 * an empty BitSet if not found or {@code null} array input
2204 * @since 3.10
2205 */
2206 public static BitSet indexesOf(final int[] array, final int valueToFind, int startIndex) {
2207 final BitSet bitSet = new BitSet();
2208 if (array == null) {
2209 return bitSet;
2210 }
2211 while (startIndex < array.length) {
2212 startIndex = indexOf(array, valueToFind, startIndex);
2213
2214 if (startIndex == INDEX_NOT_FOUND) {
2215 break;
2216 }
2217 bitSet.set(startIndex);
2218 ++startIndex;
2219 }
2220 return bitSet;
2221 }
2222
2223 /**
2224 * Finds the indices of the given value in the array.
2225 *
2226 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2227 *
2228 * @param array the array to search for the object, may be {@code null}
2229 * @param valueToFind the value to find
2230 * @return a BitSet of all the indices of the value within the array,
2231 * an empty BitSet if not found or {@code null} array input
2232 * @since 3.10
2233 */
2234 public static BitSet indexesOf(final long[] array, final long valueToFind) {
2235 return indexesOf(array, valueToFind, 0);
2236 }
2237
2238 /**
2239 * Finds the indices of the given value in the array starting at the given index.
2240 *
2241 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2242 *
2243 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2244 * length will return an empty BitSet.</p>
2245 *
2246 * @param array the array to search for the object, may be {@code null}
2247 * @param valueToFind the value to find
2248 * @param startIndex the index to start searching at
2249 * @return a BitSet of all the indices of the value within the array,
2250 * an empty BitSet if not found or {@code null} array input
2251 * @since 3.10
2252 */
2253 public static BitSet indexesOf(final long[] array, final long valueToFind, int startIndex) {
2254 final BitSet bitSet = new BitSet();
2255 if (array == null) {
2256 return bitSet;
2257 }
2258 while (startIndex < array.length) {
2259 startIndex = indexOf(array, valueToFind, startIndex);
2260 if (startIndex == INDEX_NOT_FOUND) {
2261 break;
2262 }
2263 bitSet.set(startIndex);
2264 ++startIndex;
2265 }
2266 return bitSet;
2267 }
2268
2269 /**
2270 * Finds the indices of the given object in the array.
2271 *
2272 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2273 *
2274 * @param array the array to search for the object, may be {@code null}.
2275 * @param objectToFind the object to find, may be {@code null}.
2276 * @return a BitSet of all the indices of the object within the array,
2277 * an empty BitSet if not found or {@code null} array input
2278 * @since 3.10
2279 */
2280 public static BitSet indexesOf(final Object[] array, final Object objectToFind) {
2281 return indexesOf(array, objectToFind, 0);
2282 }
2283
2284 /**
2285 * Finds the indices of the given object in the array starting at the given index.
2286 *
2287 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2288 *
2289 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2290 * length will return an empty BitSet.</p>
2291 *
2292 * @param array the array to search for the object, may be {@code null}.
2293 * @param objectToFind the object to find, may be {@code null}.
2294 * @param startIndex the index to start searching at
2295 * @return a BitSet of all the indices of the object within the array starting at the index,
2296 * an empty BitSet if not found or {@code null} array input
2297 * @since 3.10
2298 */
2299 public static BitSet indexesOf(final Object[] array, final Object objectToFind, int startIndex) {
2300 final BitSet bitSet = new BitSet();
2301 if (array == null) {
2302 return bitSet;
2303 }
2304 while (startIndex < array.length) {
2305 startIndex = indexOf(array, objectToFind, startIndex);
2306 if (startIndex == INDEX_NOT_FOUND) {
2307 break;
2308 }
2309 bitSet.set(startIndex);
2310 ++startIndex;
2311 }
2312 return bitSet;
2313 }
2314
2315 /**
2316 * Finds the indices of the given value in the array.
2317 *
2318 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2319 *
2320 * @param array the array to search for the object, may be {@code null}
2321 * @param valueToFind the value to find
2322 * @return a BitSet of all the indices of the value within the array,
2323 * an empty BitSet if not found or {@code null} array input
2324 * @since 3.10
2325 */
2326 public static BitSet indexesOf(final short[] array, final short valueToFind) {
2327 return indexesOf(array, valueToFind, 0);
2328 }
2329
2330 /**
2331 * Finds the indices of the given value in the array starting at the given index.
2332 *
2333 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2334 *
2335 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2336 * length will return an empty BitSet.</p>
2337 *
2338 * @param array the array to search for the object, may be {@code null}
2339 * @param valueToFind the value to find
2340 * @param startIndex the index to start searching at
2341 * @return a BitSet of all the indices of the value within the array,
2342 * an empty BitSet if not found or {@code null} array input
2343 * @since 3.10
2344 */
2345 public static BitSet indexesOf(final short[] array, final short valueToFind, int startIndex) {
2346 final BitSet bitSet = new BitSet();
2347 if (array == null) {
2348 return bitSet;
2349 }
2350 while (startIndex < array.length) {
2351 startIndex = indexOf(array, valueToFind, startIndex);
2352 if (startIndex == INDEX_NOT_FOUND) {
2353 break;
2354 }
2355 bitSet.set(startIndex);
2356 ++startIndex;
2357 }
2358 return bitSet;
2359 }
2360
2361 /**
2362 * Finds the index of the given value in the array.
2363 * <p>
2364 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2365 * </p>
2366 *
2367 * @param array the array to search for the object, may be {@code null}
2368 * @param valueToFind the value to find
2369 * @return the index of the value within the array,
2370 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2371 */
2372 public static int indexOf(final boolean[] array, final boolean valueToFind) {
2373 return indexOf(array, valueToFind, 0);
2374 }
2375
2376 /**
2377 * Finds the index of the given value in the array starting at the given index.
2378 * <p>
2379 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2380 * </p>
2381 * <p>
2382 * A negative startIndex is treated as zero. A startIndex larger than the array
2383 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2384 * </p>
2385 *
2386 * @param array the array to search for the object, may be {@code null}
2387 * @param valueToFind the value to find
2388 * @param startIndex the index to start searching at
2389 * @return the index of the value within the array,
2390 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
2391 * array input
2392 */
2393 public static int indexOf(final boolean[] array, final boolean valueToFind, final int startIndex) {
2394 if (isEmpty(array)) {
2395 return INDEX_NOT_FOUND;
2396 }
2397 for (int i = max0(startIndex); i < array.length; i++) {
2398 if (valueToFind == array[i]) {
2399 return i;
2400 }
2401 }
2402 return INDEX_NOT_FOUND;
2403 }
2404
2405 /**
2406 * Finds the index of the given value in the array.
2407 * <p>
2408 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2409 * </p>
2410 *
2411 * @param array the array to search for the object, may be {@code null}
2412 * @param valueToFind the value to find
2413 * @return the index of the value within the array,
2414 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2415 */
2416 public static int indexOf(final byte[] array, final byte valueToFind) {
2417 return indexOf(array, valueToFind, 0);
2418 }
2419
2420 /**
2421 * Finds the index of the given value in the array starting at the given index.
2422 * <p>
2423 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2424 * </p>
2425 * <p>
2426 * A negative startIndex is treated as zero. A startIndex larger than the array
2427 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2428 * </p>
2429 *
2430 * @param array the array to search for the object, may be {@code null}
2431 * @param valueToFind the value to find
2432 * @param startIndex the index to start searching at
2433 * @return the index of the value within the array,
2434 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2435 */
2436 public static int indexOf(final byte[] array, final byte valueToFind, final int startIndex) {
2437 if (array == null) {
2438 return INDEX_NOT_FOUND;
2439 }
2440 for (int i = max0(startIndex); i < array.length; i++) {
2441 if (valueToFind == array[i]) {
2442 return i;
2443 }
2444 }
2445 return INDEX_NOT_FOUND;
2446 }
2447
2448 /**
2449 * Finds the index of the given value in the array.
2450 * <p>
2451 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2452 * </p>
2453 *
2454 * @param array the array to search for the object, may be {@code null}
2455 * @param valueToFind the value to find
2456 * @return the index of the value within the array,
2457 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2458 * @since 2.1
2459 */
2460 public static int indexOf(final char[] array, final char valueToFind) {
2461 return indexOf(array, valueToFind, 0);
2462 }
2463
2464 /**
2465 * Finds the index of the given value in the array starting at the given index.
2466 * <p>
2467 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2468 * </p>
2469 * <p>
2470 * A negative startIndex is treated as zero. A startIndex larger than the array
2471 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2472 * </p>
2473 *
2474 * @param array the array to search for the object, may be {@code null}
2475 * @param valueToFind the value to find
2476 * @param startIndex the index to start searching at
2477 * @return the index of the value within the array,
2478 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2479 * @since 2.1
2480 */
2481 public static int indexOf(final char[] array, final char valueToFind, final int startIndex) {
2482 if (array == null) {
2483 return INDEX_NOT_FOUND;
2484 }
2485 for (int i = max0(startIndex); i < array.length; i++) {
2486 if (valueToFind == array[i]) {
2487 return i;
2488 }
2489 }
2490 return INDEX_NOT_FOUND;
2491 }
2492
2493 /**
2494 * Finds the index of the given value in the array.
2495 * <p>
2496 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2497 * </p>
2498 *
2499 * @param array the array to search for the object, may be {@code null}
2500 * @param valueToFind the value to find
2501 * @return the index of the value within the array,
2502 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2503 */
2504 public static int indexOf(final double[] array, final double valueToFind) {
2505 return indexOf(array, valueToFind, 0);
2506 }
2507
2508 /**
2509 * Finds the index of the given value within a given tolerance in the array.
2510 * This method will return the index of the first value which falls between the region
2511 * defined by valueToFind - tolerance and valueToFind + tolerance.
2512 * <p>
2513 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2514 * </p>
2515 *
2516 * @param array the array to search for the object, may be {@code null}
2517 * @param valueToFind the value to find
2518 * @param tolerance tolerance of the search
2519 * @return the index of the value within the array,
2520 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2521 */
2522 public static int indexOf(final double[] array, final double valueToFind, final double tolerance) {
2523 return indexOf(array, valueToFind, 0, tolerance);
2524 }
2525
2526 /**
2527 * Finds the index of the given value in the array starting at the given index.
2528 * <p>
2529 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2530 * </p>
2531 * <p>
2532 * A negative startIndex is treated as zero. A startIndex larger than the array
2533 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2534 * </p>
2535 *
2536 * @param array the array to search for the object, may be {@code null}
2537 * @param valueToFind the value to find
2538 * @param startIndex the index to start searching at
2539 * @return the index of the value within the array,
2540 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2541 */
2542 public static int indexOf(final double[] array, final double valueToFind, final int startIndex) {
2543 if (isEmpty(array)) {
2544 return INDEX_NOT_FOUND;
2545 }
2546 final boolean searchNaN = Double.isNaN(valueToFind);
2547 for (int i = max0(startIndex); i < array.length; i++) {
2548 final double element = array[i];
2549 if (valueToFind == element || searchNaN && Double.isNaN(element)) {
2550 return i;
2551 }
2552 }
2553 return INDEX_NOT_FOUND;
2554 }
2555
2556 /**
2557 * Finds the index of the given value in the array starting at the given index.
2558 * This method will return the index of the first value which falls between the region
2559 * defined by valueToFind - tolerance and valueToFind + tolerance.
2560 * <p>
2561 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2562 * </p>
2563 * <p>
2564 * A negative startIndex is treated as zero. A startIndex larger than the array
2565 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2566 * </p>
2567 *
2568 * @param array the array to search for the object, may be {@code null}
2569 * @param valueToFind the value to find
2570 * @param startIndex the index to start searching at
2571 * @param tolerance tolerance of the search
2572 * @return the index of the value within the array,
2573 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2574 */
2575 public static int indexOf(final double[] array, final double valueToFind, final int startIndex, final double tolerance) {
2576 if (isEmpty(array)) {
2577 return INDEX_NOT_FOUND;
2578 }
2579 final double min = valueToFind - tolerance;
2580 final double max = valueToFind + tolerance;
2581 for (int i = max0(startIndex); i < array.length; i++) {
2582 if (array[i] >= min && array[i] <= max) {
2583 return i;
2584 }
2585 }
2586 return INDEX_NOT_FOUND;
2587 }
2588
2589 /**
2590 * Finds the index of the given value in the array.
2591 * <p>
2592 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2593 * </p>
2594 *
2595 * @param array the array to search for the object, may be {@code null}
2596 * @param valueToFind the value to find
2597 * @return the index of the value within the array,
2598 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2599 */
2600 public static int indexOf(final float[] array, final float valueToFind) {
2601 return indexOf(array, valueToFind, 0);
2602 }
2603
2604 /**
2605 * Finds the index of the given value in the array starting at the given index.
2606 * <p>
2607 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2608 * </p>
2609 * <p>
2610 * A negative startIndex is treated as zero. A startIndex larger than the array
2611 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2612 * </p>
2613 *
2614 * @param array the array to search for the object, may be {@code null}
2615 * @param valueToFind the value to find
2616 * @param startIndex the index to start searching at
2617 * @return the index of the value within the array,
2618 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2619 */
2620 public static int indexOf(final float[] array, final float valueToFind, final int startIndex) {
2621 if (isEmpty(array)) {
2622 return INDEX_NOT_FOUND;
2623 }
2624 final boolean searchNaN = Float.isNaN(valueToFind);
2625 for (int i = max0(startIndex); i < array.length; i++) {
2626 final float element = array[i];
2627 if (valueToFind == element || searchNaN && Float.isNaN(element)) {
2628 return i;
2629 }
2630 }
2631 return INDEX_NOT_FOUND;
2632 }
2633
2634 /**
2635 * Finds the index of the given value in the array.
2636 * <p>
2637 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2638 * </p>
2639 *
2640 * @param array the array to search for the object, may be {@code null}
2641 * @param valueToFind the value to find
2642 * @return the index of the value within the array,
2643 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2644 */
2645 public static int indexOf(final int[] array, final int valueToFind) {
2646 return indexOf(array, valueToFind, 0);
2647 }
2648
2649 /**
2650 * Finds the index of the given value in the array starting at the given index.
2651 * <p>
2652 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2653 * </p>
2654 * <p>
2655 * A negative startIndex is treated as zero. A startIndex larger than the array
2656 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2657 * </p>
2658 *
2659 * @param array the array to search for the object, may be {@code null}
2660 * @param valueToFind the value to find
2661 * @param startIndex the index to start searching at
2662 * @return the index of the value within the array,
2663 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2664 */
2665 public static int indexOf(final int[] array, final int valueToFind, final int startIndex) {
2666 if (array == null) {
2667 return INDEX_NOT_FOUND;
2668 }
2669 for (int i = max0(startIndex); i < array.length; i++) {
2670 if (valueToFind == array[i]) {
2671 return i;
2672 }
2673 }
2674 return INDEX_NOT_FOUND;
2675 }
2676
2677 /**
2678 * Finds the index of the given value in the array.
2679 * <p>
2680 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2681 * </p>
2682 *
2683 * @param array the array to search for the object, may be {@code null}
2684 * @param valueToFind the value to find
2685 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
2686 * array input
2687 */
2688 public static int indexOf(final long[] array, final long valueToFind) {
2689 return indexOf(array, valueToFind, 0);
2690 }
2691
2692 /**
2693 * Finds the index of the given value in the array starting at the given index.
2694 * <p>
2695 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2696 * </p>
2697 * <p>
2698 * A negative startIndex is treated as zero. A startIndex larger than the array
2699 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2700 * </p>
2701 *
2702 * @param array the array to search for the object, may be {@code null}
2703 * @param valueToFind the value to find
2704 * @param startIndex the index to start searching at
2705 * @return the index of the value within the array,
2706 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2707 */
2708 public static int indexOf(final long[] array, final long valueToFind, final int startIndex) {
2709 if (array == null) {
2710 return INDEX_NOT_FOUND;
2711 }
2712 for (int i = max0(startIndex); i < array.length; i++) {
2713 if (valueToFind == array[i]) {
2714 return i;
2715 }
2716 }
2717 return INDEX_NOT_FOUND;
2718 }
2719
2720 /**
2721 * Finds the index of the given object in the array.
2722 * <p>
2723 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2724 * </p>
2725 *
2726 * @param array the array to search for the object, may be {@code null}.
2727 * @param objectToFind the object to find, may be {@code null}.
2728 * @return the index of the object within the array,
2729 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2730 */
2731 public static int indexOf(final Object[] array, final Object objectToFind) {
2732 return indexOf(array, objectToFind, 0);
2733 }
2734
2735 /**
2736 * Finds the index of the given object in the array starting at the given index.
2737 * <p>
2738 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2739 * </p>
2740 * <p>
2741 * A negative startIndex is treated as zero. A startIndex larger than the array
2742 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2743 * </p>
2744 *
2745 * @param array the array to search for the object, may be {@code null}.
2746 * @param objectToFind the object to find, may be {@code null}.
2747 * @param startIndex the index to start searching at
2748 * @return the index of the object within the array starting at the index,
2749 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2750 */
2751 public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
2752 if (array == null) {
2753 return INDEX_NOT_FOUND;
2754 }
2755 startIndex = max0(startIndex);
2756 if (objectToFind == null) {
2757 for (int i = startIndex; i < array.length; i++) {
2758 if (array[i] == null) {
2759 return i;
2760 }
2761 }
2762 } else {
2763 for (int i = startIndex; i < array.length; i++) {
2764 if (objectToFind.equals(array[i])) {
2765 return i;
2766 }
2767 }
2768 }
2769 return INDEX_NOT_FOUND;
2770 }
2771
2772 /**
2773 * Finds the index of the given value in the array.
2774 * <p>
2775 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2776 * </p>
2777 *
2778 * @param array the array to search for the object, may be {@code null}
2779 * @param valueToFind the value to find
2780 * @return the index of the value within the array,
2781 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2782 */
2783 public static int indexOf(final short[] array, final short valueToFind) {
2784 return indexOf(array, valueToFind, 0);
2785 }
2786
2787 /**
2788 * Finds the index of the given value in the array starting at the given index.
2789 * <p>
2790 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2791 * </p>
2792 * <p>
2793 * A negative startIndex is treated as zero. A startIndex larger than the array
2794 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2795 * </p>
2796 *
2797 * @param array the array to search for the object, may be {@code null}
2798 * @param valueToFind the value to find
2799 * @param startIndex the index to start searching at
2800 * @return the index of the value within the array,
2801 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2802 */
2803 public static int indexOf(final short[] array, final short valueToFind, final int startIndex) {
2804 if (array == null) {
2805 return INDEX_NOT_FOUND;
2806 }
2807 for (int i = max0(startIndex); i < array.length; i++) {
2808 if (valueToFind == array[i]) {
2809 return i;
2810 }
2811 }
2812 return INDEX_NOT_FOUND;
2813 }
2814
2815 /**
2816 * Inserts elements into an array at the given index (starting from zero).
2817 *
2818 * <p>When an array is returned, it is always a new array.</p>
2819 *
2820 * <pre>
2821 * ArrayUtils.insert(index, null, null) = null
2822 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
2823 * ArrayUtils.insert(index, null, values) = null
2824 * </pre>
2825 *
2826 * @param index the position within {@code array} to insert the new values
2827 * @param array the array to insert the values into, may be {@code null}
2828 * @param values the new values to insert, may be {@code null}
2829 * @return The new array or {@code null} if the given array is {@code null}.
2830 * @throws IndexOutOfBoundsException if {@code array} is provided
2831 * and either {@code index < 0} or {@code index > array.length}
2832 * @since 3.6
2833 */
2834 public static boolean[] insert(final int index, final boolean[] array, final boolean... values) {
2835 if (array == null) {
2836 return null;
2837 }
2838 if (isEmpty(values)) {
2839 return clone(array);
2840 }
2841 if (index < 0 || index > array.length) {
2842 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
2843 }
2844 final boolean[] result = new boolean[array.length + values.length];
2845 System.arraycopy(values, 0, result, index, values.length);
2846 if (index > 0) {
2847 System.arraycopy(array, 0, result, 0, index);
2848 }
2849 if (index < array.length) {
2850 System.arraycopy(array, index, result, index + values.length, array.length - index);
2851 }
2852 return result;
2853 }
2854
2855 /**
2856 * Inserts elements into an array at the given index (starting from zero).
2857 *
2858 * <p>When an array is returned, it is always a new array.</p>
2859 *
2860 * <pre>
2861 * ArrayUtils.insert(index, null, null) = null
2862 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
2863 * ArrayUtils.insert(index, null, values) = null
2864 * </pre>
2865 *
2866 * @param index the position within {@code array} to insert the new values
2867 * @param array the array to insert the values into, may be {@code null}
2868 * @param values the new values to insert, may be {@code null}
2869 * @return The new array or {@code null} if the given array is {@code null}.
2870 * @throws IndexOutOfBoundsException if {@code array} is provided
2871 * and either {@code index < 0} or {@code index > array.length}
2872 * @since 3.6
2873 */
2874 public static byte[] insert(final int index, final byte[] array, final byte... values) {
2875 if (array == null) {
2876 return null;
2877 }
2878 if (isEmpty(values)) {
2879 return clone(array);
2880 }
2881 if (index < 0 || index > array.length) {
2882 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
2883 }
2884 final byte[] result = new byte[array.length + values.length];
2885 System.arraycopy(values, 0, result, index, values.length);
2886 if (index > 0) {
2887 System.arraycopy(array, 0, result, 0, index);
2888 }
2889 if (index < array.length) {
2890 System.arraycopy(array, index, result, index + values.length, array.length - index);
2891 }
2892 return result;
2893 }
2894
2895 /**
2896 * Inserts elements into an array at the given index (starting from zero).
2897 *
2898 * <p>When an array is returned, it is always a new array.</p>
2899 *
2900 * <pre>
2901 * ArrayUtils.insert(index, null, null) = null
2902 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
2903 * ArrayUtils.insert(index, null, values) = null
2904 * </pre>
2905 *
2906 * @param index the position within {@code array} to insert the new values
2907 * @param array the array to insert the values into, may be {@code null}
2908 * @param values the new values to insert, may be {@code null}
2909 * @return The new array or {@code null} if the given array is {@code null}.
2910 * @throws IndexOutOfBoundsException if {@code array} is provided
2911 * and either {@code index < 0} or {@code index > array.length}
2912 * @since 3.6
2913 */
2914 public static char[] insert(final int index, final char[] array, final char... values) {
2915 if (array == null) {
2916 return null;
2917 }
2918 if (isEmpty(values)) {
2919 return clone(array);
2920 }
2921 if (index < 0 || index > array.length) {
2922 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
2923 }
2924 final char[] result = new char[array.length + values.length];
2925 System.arraycopy(values, 0, result, index, values.length);
2926 if (index > 0) {
2927 System.arraycopy(array, 0, result, 0, index);
2928 }
2929 if (index < array.length) {
2930 System.arraycopy(array, index, result, index + values.length, array.length - index);
2931 }
2932 return result;
2933 }
2934
2935 /**
2936 * Inserts elements into an array at the given index (starting from zero).
2937 *
2938 * <p>When an array is returned, it is always a new array.</p>
2939 *
2940 * <pre>
2941 * ArrayUtils.insert(index, null, null) = null
2942 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
2943 * ArrayUtils.insert(index, null, values) = null
2944 * </pre>
2945 *
2946 * @param index the position within {@code array} to insert the new values
2947 * @param array the array to insert the values into, may be {@code null}
2948 * @param values the new values to insert, may be {@code null}
2949 * @return The new array or {@code null} if the given array is {@code null}.
2950 * @throws IndexOutOfBoundsException if {@code array} is provided
2951 * and either {@code index < 0} or {@code index > array.length}
2952 * @since 3.6
2953 */
2954 public static double[] insert(final int index, final double[] array, final double... values) {
2955 if (array == null) {
2956 return null;
2957 }
2958 if (isEmpty(values)) {
2959 return clone(array);
2960 }
2961 if (index < 0 || index > array.length) {
2962 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
2963 }
2964 final double[] result = new double[array.length + values.length];
2965 System.arraycopy(values, 0, result, index, values.length);
2966 if (index > 0) {
2967 System.arraycopy(array, 0, result, 0, index);
2968 }
2969 if (index < array.length) {
2970 System.arraycopy(array, index, result, index + values.length, array.length - index);
2971 }
2972 return result;
2973 }
2974
2975 /**
2976 * Inserts elements into an array at the given index (starting from zero).
2977 *
2978 * <p>When an array is returned, it is always a new array.</p>
2979 *
2980 * <pre>
2981 * ArrayUtils.insert(index, null, null) = null
2982 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
2983 * ArrayUtils.insert(index, null, values) = null
2984 * </pre>
2985 *
2986 * @param index the position within {@code array} to insert the new values
2987 * @param array the array to insert the values into, may be {@code null}
2988 * @param values the new values to insert, may be {@code null}
2989 * @return The new array or {@code null} if the given array is {@code null}.
2990 * @throws IndexOutOfBoundsException if {@code array} is provided
2991 * and either {@code index < 0} or {@code index > array.length}
2992 * @since 3.6
2993 */
2994 public static float[] insert(final int index, final float[] array, final float... values) {
2995 if (array == null) {
2996 return null;
2997 }
2998 if (isEmpty(values)) {
2999 return clone(array);
3000 }
3001 if (index < 0 || index > array.length) {
3002 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3003 }
3004 final float[] result = new float[array.length + values.length];
3005 System.arraycopy(values, 0, result, index, values.length);
3006 if (index > 0) {
3007 System.arraycopy(array, 0, result, 0, index);
3008 }
3009 if (index < array.length) {
3010 System.arraycopy(array, index, result, index + values.length, array.length - index);
3011 }
3012 return result;
3013 }
3014
3015 /**
3016 * Inserts elements into an array at the given index (starting from zero).
3017 *
3018 * <p>When an array is returned, it is always a new array.</p>
3019 *
3020 * <pre>
3021 * ArrayUtils.insert(index, null, null) = null
3022 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3023 * ArrayUtils.insert(index, null, values) = null
3024 * </pre>
3025 *
3026 * @param index the position within {@code array} to insert the new values
3027 * @param array the array to insert the values into, may be {@code null}
3028 * @param values the new values to insert, may be {@code null}
3029 * @return The new array or {@code null} if the given array is {@code null}.
3030 * @throws IndexOutOfBoundsException if {@code array} is provided
3031 * and either {@code index < 0} or {@code index > array.length}
3032 * @since 3.6
3033 */
3034 public static int[] insert(final int index, final int[] array, final int... values) {
3035 if (array == null) {
3036 return null;
3037 }
3038 if (isEmpty(values)) {
3039 return clone(array);
3040 }
3041 if (index < 0 || index > array.length) {
3042 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3043 }
3044 final int[] result = new int[array.length + values.length];
3045 System.arraycopy(values, 0, result, index, values.length);
3046 if (index > 0) {
3047 System.arraycopy(array, 0, result, 0, index);
3048 }
3049 if (index < array.length) {
3050 System.arraycopy(array, index, result, index + values.length, array.length - index);
3051 }
3052 return result;
3053 }
3054
3055 /**
3056 * Inserts elements into an array at the given index (starting from zero).
3057 *
3058 * <p>When an array is returned, it is always a new array.</p>
3059 *
3060 * <pre>
3061 * ArrayUtils.insert(index, null, null) = null
3062 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3063 * ArrayUtils.insert(index, null, values) = null
3064 * </pre>
3065 *
3066 * @param index the position within {@code array} to insert the new values
3067 * @param array the array to insert the values into, may be {@code null}
3068 * @param values the new values to insert, may be {@code null}
3069 * @return The new array or {@code null} if the given array is {@code null}.
3070 * @throws IndexOutOfBoundsException if {@code array} is provided
3071 * and either {@code index < 0} or {@code index > array.length}
3072 * @since 3.6
3073 */
3074 public static long[] insert(final int index, final long[] array, final long... values) {
3075 if (array == null) {
3076 return null;
3077 }
3078 if (isEmpty(values)) {
3079 return clone(array);
3080 }
3081 if (index < 0 || index > array.length) {
3082 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3083 }
3084 final long[] result = new long[array.length + values.length];
3085 System.arraycopy(values, 0, result, index, values.length);
3086 if (index > 0) {
3087 System.arraycopy(array, 0, result, 0, index);
3088 }
3089 if (index < array.length) {
3090 System.arraycopy(array, index, result, index + values.length, array.length - index);
3091 }
3092 return result;
3093 }
3094
3095 /**
3096 * Inserts elements into an array at the given index (starting from zero).
3097 *
3098 * <p>When an array is returned, it is always a new array.</p>
3099 *
3100 * <pre>
3101 * ArrayUtils.insert(index, null, null) = null
3102 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3103 * ArrayUtils.insert(index, null, values) = null
3104 * </pre>
3105 *
3106 * @param index the position within {@code array} to insert the new values
3107 * @param array the array to insert the values into, may be {@code null}
3108 * @param values the new values to insert, may be {@code null}
3109 * @return The new array or {@code null} if the given array is {@code null}.
3110 * @throws IndexOutOfBoundsException if {@code array} is provided
3111 * and either {@code index < 0} or {@code index > array.length}
3112 * @since 3.6
3113 */
3114 public static short[] insert(final int index, final short[] array, final short... values) {
3115 if (array == null) {
3116 return null;
3117 }
3118 if (isEmpty(values)) {
3119 return clone(array);
3120 }
3121 if (index < 0 || index > array.length) {
3122 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3123 }
3124 final short[] result = new short[array.length + values.length];
3125 System.arraycopy(values, 0, result, index, values.length);
3126 if (index > 0) {
3127 System.arraycopy(array, 0, result, 0, index);
3128 }
3129 if (index < array.length) {
3130 System.arraycopy(array, index, result, index + values.length, array.length - index);
3131 }
3132 return result;
3133 }
3134
3135 /**
3136 * Inserts elements into an array at the given index (starting from zero).
3137 *
3138 * <p>When an array is returned, it is always a new array.</p>
3139 *
3140 * <pre>
3141 * ArrayUtils.insert(index, null, null) = null
3142 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3143 * ArrayUtils.insert(index, null, values) = null
3144 * </pre>
3145 *
3146 * @param <T> The type of elements in {@code array} and {@code values}
3147 * @param index the position within {@code array} to insert the new values
3148 * @param array the array to insert the values into, may be {@code null}
3149 * @param values the new values to insert, may be {@code null}
3150 * @return The new array or {@code null} if the given array is {@code null}.
3151 * @throws IndexOutOfBoundsException if {@code array} is provided
3152 * and either {@code index < 0} or {@code index > array.length}
3153 * @since 3.6
3154 */
3155 @SafeVarargs
3156 public static <T> T[] insert(final int index, final T[] array, final T... values) {
3157 /*
3158 * Note on use of @SafeVarargs:
3159 *
3160 * By returning null when 'array' is null, we avoid returning the vararg
3161 * array to the caller. We also avoid relying on the type of the vararg
3162 * array, by inspecting the component type of 'array'.
3163 */
3164 if (array == null) {
3165 return null;
3166 }
3167 if (isEmpty(values)) {
3168 return clone(array);
3169 }
3170 if (index < 0 || index > array.length) {
3171 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3172 }
3173 final Class<T> type = getComponentType(array);
3174 final int length = array.length + values.length;
3175 final T[] result = newInstance(type, length);
3176 System.arraycopy(values, 0, result, index, values.length);
3177 if (index > 0) {
3178 System.arraycopy(array, 0, result, 0, index);
3179 }
3180 if (index < array.length) {
3181 System.arraycopy(array, index, result, index + values.length, array.length - index);
3182 }
3183 return result;
3184 }
3185
3186 /**
3187 * Checks if an array is empty or {@code null}.
3188 *
3189 * @param array the array to test
3190 * @return {@code true} if the array is empty or {@code null}
3191 */
3192 private static boolean isArrayEmpty(final Object array) {
3193 return getLength(array) == 0;
3194 }
3195
3196 /**
3197 * Tests whether a given array can safely be accessed at the given index.
3198 *
3199 * <pre>
3200 * ArrayUtils.isArrayIndexValid(null, 0) = false
3201 * ArrayUtils.isArrayIndexValid([], 0) = false
3202 * ArrayUtils.isArrayIndexValid(["a"], 0) = true
3203 * </pre>
3204 *
3205 * @param <T> the component type of the array
3206 * @param array the array to inspect, may be {@code null}.
3207 * @param index the index of the array to be inspected
3208 * @return Whether the given index is safely-accessible in the given array
3209 * @since 3.8
3210 */
3211 public static <T> boolean isArrayIndexValid(final T[] array, final int index) {
3212 return index >= 0 && getLength(array) > index;
3213 }
3214
3215 /**
3216 * Tests whether an array of primitive booleans is empty or {@code null}.
3217 *
3218 * @param array the array to test
3219 * @return {@code true} if the array is empty or {@code null}
3220 * @since 2.1
3221 */
3222 public static boolean isEmpty(final boolean[] array) {
3223 return isArrayEmpty(array);
3224 }
3225
3226 /**
3227 * Tests whether an array of primitive bytes is empty or {@code null}.
3228 *
3229 * @param array the array to test
3230 * @return {@code true} if the array is empty or {@code null}
3231 * @since 2.1
3232 */
3233 public static boolean isEmpty(final byte[] array) {
3234 return isArrayEmpty(array);
3235 }
3236
3237 /**
3238 * Tests whether an array of primitive chars is empty or {@code null}.
3239 *
3240 * @param array the array to test
3241 * @return {@code true} if the array is empty or {@code null}
3242 * @since 2.1
3243 */
3244 public static boolean isEmpty(final char[] array) {
3245 return isArrayEmpty(array);
3246 }
3247
3248 /**
3249 * Tests whether an array of primitive doubles is empty or {@code null}.
3250 *
3251 * @param array the array to test
3252 * @return {@code true} if the array is empty or {@code null}
3253 * @since 2.1
3254 */
3255 public static boolean isEmpty(final double[] array) {
3256 return isArrayEmpty(array);
3257 }
3258
3259 /**
3260 * Tests whether an array of primitive floats is empty or {@code null}.
3261 *
3262 * @param array the array to test
3263 * @return {@code true} if the array is empty or {@code null}
3264 * @since 2.1
3265 */
3266 public static boolean isEmpty(final float[] array) {
3267 return isArrayEmpty(array);
3268 }
3269
3270 /**
3271 * Tests whether an array of primitive ints is empty or {@code null}.
3272 *
3273 * @param array the array to test
3274 * @return {@code true} if the array is empty or {@code null}
3275 * @since 2.1
3276 */
3277 public static boolean isEmpty(final int[] array) {
3278 return isArrayEmpty(array);
3279 }
3280
3281 /**
3282 * Tests whether an array of primitive longs is empty or {@code null}.
3283 *
3284 * @param array the array to test
3285 * @return {@code true} if the array is empty or {@code null}
3286 * @since 2.1
3287 */
3288 public static boolean isEmpty(final long[] array) {
3289 return isArrayEmpty(array);
3290 }
3291
3292 /**
3293 * Tests whether an array of Objects is empty or {@code null}.
3294 *
3295 * @param array the array to test
3296 * @return {@code true} if the array is empty or {@code null}
3297 * @since 2.1
3298 */
3299 public static boolean isEmpty(final Object[] array) {
3300 return isArrayEmpty(array);
3301 }
3302
3303 /**
3304 * Tests whether an array of primitive shorts is empty or {@code null}.
3305 *
3306 * @param array the array to test
3307 * @return {@code true} if the array is empty or {@code null}
3308 * @since 2.1
3309 */
3310 public static boolean isEmpty(final short[] array) {
3311 return isArrayEmpty(array);
3312 }
3313
3314 /**
3315 * Tests whether two arrays have equal content, using equals(), handling multidimensional arrays
3316 * correctly.
3317 * <p>
3318 * Multi-dimensional primitive arrays are also handled correctly by this method.
3319 * </p>
3320 *
3321 * @param array1 the left-hand side array to compare, may be {@code null}
3322 * @param array2 the right-hand side array to compare, may be {@code null}
3323 * @return {@code true} if the arrays are equal
3324 * @deprecated this method has been replaced by {@code java.util.Objects.deepEquals(Object, Object)} and will be
3325 * removed from future releases.
3326 */
3327 @Deprecated
3328 public static boolean isEquals(final Object array1, final Object array2) {
3329 return new EqualsBuilder().append(array1, array2).isEquals();
3330 }
3331
3332 /**
3333 * Tests whether an array of primitive booleans is not empty and not {@code null}.
3334 *
3335 * @param array the array to test
3336 * @return {@code true} if the array is not empty and not {@code null}
3337 * @since 2.5
3338 */
3339 public static boolean isNotEmpty(final boolean[] array) {
3340 return !isEmpty(array);
3341 }
3342
3343 /**
3344 * Tests whether an array of primitive bytes is not empty and not {@code null}.
3345 *
3346 * @param array the array to test
3347 * @return {@code true} if the array is not empty and not {@code null}
3348 * @since 2.5
3349 */
3350 public static boolean isNotEmpty(final byte[] array) {
3351 return !isEmpty(array);
3352 }
3353
3354 /**
3355 * Tests whether an array of primitive chars is not empty and not {@code null}.
3356 *
3357 * @param array the array to test
3358 * @return {@code true} if the array is not empty and not {@code null}
3359 * @since 2.5
3360 */
3361 public static boolean isNotEmpty(final char[] array) {
3362 return !isEmpty(array);
3363 }
3364
3365 /**
3366 * Tests whether an array of primitive doubles is not empty and not {@code null}.
3367 *
3368 * @param array the array to test
3369 * @return {@code true} if the array is not empty and not {@code null}
3370 * @since 2.5
3371 */
3372 public static boolean isNotEmpty(final double[] array) {
3373 return !isEmpty(array);
3374 }
3375
3376 /**
3377 * Tests whether an array of primitive floats is not empty and not {@code null}.
3378 *
3379 * @param array the array to test
3380 * @return {@code true} if the array is not empty and not {@code null}
3381 * @since 2.5
3382 */
3383 public static boolean isNotEmpty(final float[] array) {
3384 return !isEmpty(array);
3385 }
3386
3387 /**
3388 * Tests whether an array of primitive ints is not empty and not {@code null}.
3389 *
3390 * @param array the array to test
3391 * @return {@code true} if the array is not empty and not {@code null}
3392 * @since 2.5
3393 */
3394 public static boolean isNotEmpty(final int[] array) {
3395 return !isEmpty(array);
3396 }
3397
3398 /**
3399 * Tests whether an array of primitive longs is not empty and not {@code null}.
3400 *
3401 * @param array the array to test
3402 * @return {@code true} if the array is not empty and not {@code null}
3403 * @since 2.5
3404 */
3405 public static boolean isNotEmpty(final long[] array) {
3406 return !isEmpty(array);
3407 }
3408
3409 /**
3410 * Tests whether an array of primitive shorts is not empty and not {@code null}.
3411 *
3412 * @param array the array to test
3413 * @return {@code true} if the array is not empty and not {@code null}
3414 * @since 2.5
3415 */
3416 public static boolean isNotEmpty(final short[] array) {
3417 return !isEmpty(array);
3418 }
3419
3420 /**
3421 * Tests whether an array of Objects is not empty and not {@code null}.
3422 *
3423 * @param <T> the component type of the array
3424 * @param array the array to test
3425 * @return {@code true} if the array is not empty and not {@code null}
3426 * @since 2.5
3427 */
3428 public static <T> boolean isNotEmpty(final T[] array) {
3429 return !isEmpty(array);
3430 }
3431
3432 /**
3433 * Tests whether two arrays are the same length, treating
3434 * {@code null} arrays as length {@code 0}.
3435 *
3436 * @param array1 the first array, may be {@code null}
3437 * @param array2 the second array, may be {@code null}
3438 * @return {@code true} if length of arrays matches, treating
3439 * {@code null} as an empty array
3440 */
3441 public static boolean isSameLength(final boolean[] array1, final boolean[] array2) {
3442 return getLength(array1) == getLength(array2);
3443 }
3444
3445 /**
3446 * Tests whether two arrays are the same length, treating
3447 * {@code null} arrays as length {@code 0}.
3448 *
3449 * @param array1 the first array, may be {@code null}
3450 * @param array2 the second array, may be {@code null}
3451 * @return {@code true} if length of arrays matches, treating
3452 * {@code null} as an empty array
3453 */
3454 public static boolean isSameLength(final byte[] array1, final byte[] array2) {
3455 return getLength(array1) == getLength(array2);
3456 }
3457
3458 /**
3459 * Tests whether two arrays are the same length, treating
3460 * {@code null} arrays as length {@code 0}.
3461 *
3462 * @param array1 the first array, may be {@code null}
3463 * @param array2 the second array, may be {@code null}
3464 * @return {@code true} if length of arrays matches, treating
3465 * {@code null} as an empty array
3466 */
3467 public static boolean isSameLength(final char[] array1, final char[] array2) {
3468 return getLength(array1) == getLength(array2);
3469 }
3470
3471 /**
3472 * Tests whether two arrays are the same length, treating
3473 * {@code null} arrays as length {@code 0}.
3474 *
3475 * @param array1 the first array, may be {@code null}
3476 * @param array2 the second array, may be {@code null}
3477 * @return {@code true} if length of arrays matches, treating
3478 * {@code null} as an empty array
3479 */
3480 public static boolean isSameLength(final double[] array1, final double[] array2) {
3481 return getLength(array1) == getLength(array2);
3482 }
3483
3484 /**
3485 * Tests whether two arrays are the same length, treating
3486 * {@code null} arrays as length {@code 0}.
3487 *
3488 * @param array1 the first array, may be {@code null}
3489 * @param array2 the second array, may be {@code null}
3490 * @return {@code true} if length of arrays matches, treating
3491 * {@code null} as an empty array
3492 */
3493 public static boolean isSameLength(final float[] array1, final float[] array2) {
3494 return getLength(array1) == getLength(array2);
3495 }
3496
3497 /**
3498 * Tests whether two arrays are the same length, treating
3499 * {@code null} arrays as length {@code 0}.
3500 *
3501 * @param array1 the first array, may be {@code null}
3502 * @param array2 the second array, may be {@code null}
3503 * @return {@code true} if length of arrays matches, treating
3504 * {@code null} as an empty array
3505 */
3506 public static boolean isSameLength(final int[] array1, final int[] array2) {
3507 return getLength(array1) == getLength(array2);
3508 }
3509
3510 /**
3511 * Tests whether two arrays are the same length, treating
3512 * {@code null} arrays as length {@code 0}.
3513 *
3514 * @param array1 the first array, may be {@code null}
3515 * @param array2 the second array, may be {@code null}
3516 * @return {@code true} if length of arrays matches, treating
3517 * {@code null} as an empty array
3518 */
3519 public static boolean isSameLength(final long[] array1, final long[] array2) {
3520 return getLength(array1) == getLength(array2);
3521 }
3522
3523 /**
3524 * Tests whether two arrays are the same length, treating
3525 * {@code null} arrays as length {@code 0}.
3526 * <p>
3527 * Any multi-dimensional aspects of the arrays are ignored.
3528 * </p>
3529 *
3530 * @param array1 the first array, may be {@code null}
3531 * @param array2 the second array, may be {@code null}
3532 * @return {@code true} if length of arrays matches, treating
3533 * {@code null} as an empty array
3534 * @since 3.11
3535 */
3536 public static boolean isSameLength(final Object array1, final Object array2) {
3537 return getLength(array1) == getLength(array2);
3538 }
3539
3540 /**
3541 * Tests whether two arrays are the same length, treating
3542 * {@code null} arrays as length {@code 0}.
3543 * <p>
3544 * Any multi-dimensional aspects of the arrays are ignored.
3545 * </p>
3546 *
3547 * @param array1 the first array, may be {@code null}
3548 * @param array2 the second array, may be {@code null}
3549 * @return {@code true} if length of arrays matches, treating
3550 * {@code null} as an empty array
3551 */
3552 public static boolean isSameLength(final Object[] array1, final Object[] array2) {
3553 return getLength(array1) == getLength(array2);
3554 }
3555
3556 /**
3557 * Tests whether two arrays are the same length, treating
3558 * {@code null} arrays as length {@code 0}.
3559 *
3560 * @param array1 the first array, may be {@code null}
3561 * @param array2 the second array, may be {@code null}
3562 * @return {@code true} if length of arrays matches, treating
3563 * {@code null} as an empty array
3564 */
3565 public static boolean isSameLength(final short[] array1, final short[] array2) {
3566 return getLength(array1) == getLength(array2);
3567 }
3568
3569 /**
3570 * Tests whether two arrays are the same type taking into account
3571 * multidimensional arrays.
3572 *
3573 * @param array1 the first array, must not be {@code null}
3574 * @param array2 the second array, must not be {@code null}
3575 * @return {@code true} if type of arrays matches
3576 * @throws IllegalArgumentException if either array is {@code null}
3577 */
3578 public static boolean isSameType(final Object array1, final Object array2) {
3579 if (array1 == null || array2 == null) {
3580 throw new IllegalArgumentException("The Array must not be null");
3581 }
3582 return array1.getClass().getName().equals(array2.getClass().getName());
3583 }
3584
3585 /**
3586 * Tests whether whether the provided array is sorted according to natural ordering
3587 * ({@code false} before {@code true}).
3588 *
3589 * @param array the array to check
3590 * @return whether the array is sorted according to natural ordering
3591 * @since 3.4
3592 */
3593 public static boolean isSorted(final boolean[] array) {
3594 if (getLength(array) < 2) {
3595 return true;
3596 }
3597 boolean previous = array[0];
3598 final int n = array.length;
3599 for (int i = 1; i < n; i++) {
3600 final boolean current = array[i];
3601 if (BooleanUtils.compare(previous, current) > 0) {
3602 return false;
3603 }
3604 previous = current;
3605 }
3606 return true;
3607 }
3608
3609 /**
3610 * Tests whether the provided array is sorted according to natural ordering.
3611 *
3612 * @param array the array to check
3613 * @return whether the array is sorted according to natural ordering
3614 * @since 3.4
3615 */
3616 public static boolean isSorted(final byte[] array) {
3617 if (getLength(array) < 2) {
3618 return true;
3619 }
3620 byte previous = array[0];
3621 final int n = array.length;
3622 for (int i = 1; i < n; i++) {
3623 final byte current = array[i];
3624 if (Byte.compare(previous, current) > 0) {
3625 return false;
3626 }
3627 previous = current;
3628 }
3629 return true;
3630 }
3631
3632 /**
3633 * Tests whether the provided array is sorted according to natural ordering.
3634 *
3635 * @param array the array to check
3636 * @return whether the array is sorted according to natural ordering
3637 * @since 3.4
3638 */
3639 public static boolean isSorted(final char[] array) {
3640 if (getLength(array) < 2) {
3641 return true;
3642 }
3643 char previous = array[0];
3644 final int n = array.length;
3645 for (int i = 1; i < n; i++) {
3646 final char current = array[i];
3647 if (CharUtils.compare(previous, current) > 0) {
3648 return false;
3649 }
3650 previous = current;
3651 }
3652 return true;
3653 }
3654
3655 /**
3656 * Tests whether the provided array is sorted according to natural ordering.
3657 *
3658 * @param array the array to check
3659 * @return whether the array is sorted according to natural ordering
3660 * @since 3.4
3661 */
3662 public static boolean isSorted(final double[] array) {
3663 if (getLength(array) < 2) {
3664 return true;
3665 }
3666 double previous = array[0];
3667 final int n = array.length;
3668 for (int i = 1; i < n; i++) {
3669 final double current = array[i];
3670 if (Double.compare(previous, current) > 0) {
3671 return false;
3672 }
3673 previous = current;
3674 }
3675 return true;
3676 }
3677
3678 /**
3679 * Tests whether the provided array is sorted according to natural ordering.
3680 *
3681 * @param array the array to check
3682 * @return whether the array is sorted according to natural ordering
3683 * @since 3.4
3684 */
3685 public static boolean isSorted(final float[] array) {
3686 if (getLength(array) < 2) {
3687 return true;
3688 }
3689 float previous = array[0];
3690 final int n = array.length;
3691 for (int i = 1; i < n; i++) {
3692 final float current = array[i];
3693 if (Float.compare(previous, current) > 0) {
3694 return false;
3695 }
3696 previous = current;
3697 }
3698 return true;
3699 }
3700
3701 /**
3702 * Tests whether the provided array is sorted according to natural ordering.
3703 *
3704 * @param array the array to check
3705 * @return whether the array is sorted according to natural ordering
3706 * @since 3.4
3707 */
3708 public static boolean isSorted(final int[] array) {
3709 if (getLength(array) < 2) {
3710 return true;
3711 }
3712 int previous = array[0];
3713 final int n = array.length;
3714 for (int i = 1; i < n; i++) {
3715 final int current = array[i];
3716 if (Integer.compare(previous, current) > 0) {
3717 return false;
3718 }
3719 previous = current;
3720 }
3721 return true;
3722 }
3723
3724 /**
3725 * Tests whether the provided array is sorted according to natural ordering.
3726 *
3727 * @param array the array to check
3728 * @return whether the array is sorted according to natural ordering
3729 * @since 3.4
3730 */
3731 public static boolean isSorted(final long[] array) {
3732 if (getLength(array) < 2) {
3733 return true;
3734 }
3735 long previous = array[0];
3736 final int n = array.length;
3737 for (int i = 1; i < n; i++) {
3738 final long current = array[i];
3739 if (Long.compare(previous, current) > 0) {
3740 return false;
3741 }
3742 previous = current;
3743 }
3744 return true;
3745 }
3746
3747 /**
3748 * Tests whether the provided array is sorted according to natural ordering.
3749 *
3750 * @param array the array to check
3751 * @return whether the array is sorted according to natural ordering
3752 * @since 3.4
3753 */
3754 public static boolean isSorted(final short[] array) {
3755 if (getLength(array) < 2) {
3756 return true;
3757 }
3758 short previous = array[0];
3759 final int n = array.length;
3760 for (int i = 1; i < n; i++) {
3761 final short current = array[i];
3762 if (Short.compare(previous, current) > 0) {
3763 return false;
3764 }
3765 previous = current;
3766 }
3767 return true;
3768 }
3769
3770 /**
3771 * Tests whether the provided array is sorted according to the class's
3772 * {@code compareTo} method.
3773 *
3774 * @param array the array to check
3775 * @param <T> the datatype of the array to check, it must implement {@link Comparable}
3776 * @return whether the array is sorted
3777 * @since 3.4
3778 */
3779 public static <T extends Comparable<? super T>> boolean isSorted(final T[] array) {
3780 return isSorted(array, Comparable::compareTo);
3781 }
3782
3783 /**
3784 * Tests whether the provided array is sorted according to the provided {@link Comparator}.
3785 *
3786 * @param array the array to check
3787 * @param comparator the {@link Comparator} to compare over
3788 * @param <T> the datatype of the array
3789 * @return whether the array is sorted
3790 * @throws NullPointerException if {@code comparator} is {@code null}
3791 * @since 3.4
3792 */
3793 public static <T> boolean isSorted(final T[] array, final Comparator<T> comparator) {
3794 Objects.requireNonNull(comparator, "comparator");
3795 if (getLength(array) < 2) {
3796 return true;
3797 }
3798 T previous = array[0];
3799 final int n = array.length;
3800 for (int i = 1; i < n; i++) {
3801 final T current = array[i];
3802 if (comparator.compare(previous, current) > 0) {
3803 return false;
3804 }
3805 previous = current;
3806 }
3807 return true;
3808 }
3809
3810 /**
3811 * Finds the last index of the given value within the array.
3812 * <p>
3813 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) if
3814 * {@code null} array input.
3815 * </p>
3816 *
3817 * @param array the array to traverse backwards looking for the object, may be {@code null}
3818 * @param valueToFind the object to find
3819 * @return the last index of the value within the array,
3820 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3821 */
3822 public static int lastIndexOf(final boolean[] array, final boolean valueToFind) {
3823 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
3824 }
3825
3826 /**
3827 * Finds the last index of the given value in the array starting at the given index.
3828 * <p>
3829 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3830 * </p>
3831 * <p>
3832 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
3833 * the array length will search from the end of the array.
3834 * </p>
3835 *
3836 * @param array the array to traverse for looking for the object, may be {@code null}
3837 * @param valueToFind the value to find
3838 * @param startIndex the start index to traverse backwards from
3839 * @return the last index of the value within the array,
3840 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3841 */
3842 public static int lastIndexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
3843 if (isEmpty(array) || startIndex < 0) {
3844 return INDEX_NOT_FOUND;
3845 }
3846 if (startIndex >= array.length) {
3847 startIndex = array.length - 1;
3848 }
3849 for (int i = startIndex; i >= 0; i--) {
3850 if (valueToFind == array[i]) {
3851 return i;
3852 }
3853 }
3854 return INDEX_NOT_FOUND;
3855 }
3856
3857 /**
3858 * Finds the last index of the given value within the array.
3859 * <p>
3860 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3861 * </p>
3862 *
3863 * @param array the array to traverse backwards looking for the object, may be {@code null}
3864 * @param valueToFind the object to find
3865 * @return the last index of the value within the array,
3866 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3867 */
3868 public static int lastIndexOf(final byte[] array, final byte valueToFind) {
3869 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
3870 }
3871
3872 /**
3873 * Finds the last index of the given value in the array starting at the given index.
3874 * <p>
3875 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3876 * </p>
3877 * <p>
3878 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
3879 * array length will search from the end of the array.
3880 * </p>
3881 *
3882 * @param array the array to traverse for looking for the object, may be {@code null}
3883 * @param valueToFind the value to find
3884 * @param startIndex the start index to traverse backwards from
3885 * @return the last index of the value within the array,
3886 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3887 */
3888 public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) {
3889 if (array == null || startIndex < 0) {
3890 return INDEX_NOT_FOUND;
3891 }
3892 if (startIndex >= array.length) {
3893 startIndex = array.length - 1;
3894 }
3895 for (int i = startIndex; i >= 0; i--) {
3896 if (valueToFind == array[i]) {
3897 return i;
3898 }
3899 }
3900 return INDEX_NOT_FOUND;
3901 }
3902
3903 /**
3904 * Finds the last index of the given value within the array.
3905 * <p>
3906 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3907 * </p>
3908 *
3909 * @param array the array to traverse backwards looking for the object, may be {@code null}
3910 * @param valueToFind the object to find
3911 * @return the last index of the value within the array,
3912 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3913 * @since 2.1
3914 */
3915 public static int lastIndexOf(final char[] array, final char valueToFind) {
3916 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
3917 }
3918
3919 /**
3920 * Finds the last index of the given value in the array starting at the given index.
3921 * <p>
3922 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3923 * </p>
3924 * <p>
3925 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
3926 * array length will search from the end of the array.
3927 * </p>
3928 *
3929 * @param array the array to traverse for looking for the object, may be {@code null}
3930 * @param valueToFind the value to find
3931 * @param startIndex the start index to traverse backwards from
3932 * @return the last index of the value within the array,
3933 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3934 * @since 2.1
3935 */
3936 public static int lastIndexOf(final char[] array, final char valueToFind, int startIndex) {
3937 if (array == null || startIndex < 0) {
3938 return INDEX_NOT_FOUND;
3939 }
3940 if (startIndex >= array.length) {
3941 startIndex = array.length - 1;
3942 }
3943 for (int i = startIndex; i >= 0; i--) {
3944 if (valueToFind == array[i]) {
3945 return i;
3946 }
3947 }
3948 return INDEX_NOT_FOUND;
3949 }
3950
3951 /**
3952 * Finds the last index of the given value within the array.
3953 * <p>
3954 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3955 * </p>
3956 *
3957 * @param array the array to traverse backwards looking for the object, may be {@code null}
3958 * @param valueToFind the object to find
3959 * @return the last index of the value within the array,
3960 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3961 */
3962 public static int lastIndexOf(final double[] array, final double valueToFind) {
3963 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
3964 }
3965
3966 /**
3967 * Finds the last index of the given value within a given tolerance in the array.
3968 * This method will return the index of the last value which falls between the region
3969 * defined by valueToFind - tolerance and valueToFind + tolerance.
3970 * <p>
3971 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3972 * </p>
3973 *
3974 * @param array the array to search for the object, may be {@code null}
3975 * @param valueToFind the value to find
3976 * @param tolerance tolerance of the search
3977 * @return the index of the value within the array,
3978 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3979 */
3980 public static int lastIndexOf(final double[] array, final double valueToFind, final double tolerance) {
3981 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
3982 }
3983
3984 /**
3985 * Finds the last index of the given value in the array starting at the given index.
3986 * <p>
3987 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3988 * </p>
3989 * <p>
3990 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
3991 * array length will search from the end of the array.
3992 * </p>
3993 *
3994 * @param array the array to traverse for looking for the object, may be {@code null}
3995 * @param valueToFind the value to find
3996 * @param startIndex the start index to traverse backwards from
3997 * @return the last index of the value within the array,
3998 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
3999 */
4000 public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) {
4001 if (isEmpty(array) || startIndex < 0) {
4002 return INDEX_NOT_FOUND;
4003 }
4004 if (startIndex >= array.length) {
4005 startIndex = array.length - 1;
4006 }
4007 for (int i = startIndex; i >= 0; i--) {
4008 if (valueToFind == array[i]) {
4009 return i;
4010 }
4011 }
4012 return INDEX_NOT_FOUND;
4013 }
4014
4015 /**
4016 * Finds the last index of the given value in the array starting at the given index.
4017 * This method will return the index of the last value which falls between the region
4018 * defined by valueToFind - tolerance and valueToFind + tolerance.
4019 * <p>
4020 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4021 * </p>
4022 * <p>
4023 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
4024 * array length will search from the end of the array.
4025 * </p>
4026 *
4027 * @param array the array to traverse for looking for the object, may be {@code null}
4028 * @param valueToFind the value to find
4029 * @param startIndex the start index to traverse backwards from
4030 * @param tolerance search for value within plus/minus this amount
4031 * @return the last index of the value within the array,
4032 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4033 */
4034 public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
4035 if (isEmpty(array) || startIndex < 0) {
4036 return INDEX_NOT_FOUND;
4037 }
4038 if (startIndex >= array.length) {
4039 startIndex = array.length - 1;
4040 }
4041 final double min = valueToFind - tolerance;
4042 final double max = valueToFind + tolerance;
4043 for (int i = startIndex; i >= 0; i--) {
4044 if (array[i] >= min && array[i] <= max) {
4045 return i;
4046 }
4047 }
4048 return INDEX_NOT_FOUND;
4049 }
4050
4051 /**
4052 * Finds the last index of the given value within the array.
4053 * <p>
4054 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4055 * </p>
4056 *
4057 * @param array the array to traverse backwards looking for the object, may be {@code null}
4058 * @param valueToFind the object to find
4059 * @return the last index of the value within the array,
4060 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4061 */
4062 public static int lastIndexOf(final float[] array, final float valueToFind) {
4063 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4064 }
4065
4066 /**
4067 * Finds the last index of the given value in the array starting at the given index.
4068 * <p>
4069 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4070 * </p>
4071 * <p>
4072 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
4073 * array length will search from the end of the array.
4074 * </p>
4075 *
4076 * @param array the array to traverse for looking for the object, may be {@code null}
4077 * @param valueToFind the value to find
4078 * @param startIndex the start index to traverse backwards from
4079 * @return the last index of the value within the array,
4080 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4081 */
4082 public static int lastIndexOf(final float[] array, final float valueToFind, int startIndex) {
4083 if (isEmpty(array) || startIndex < 0) {
4084 return INDEX_NOT_FOUND;
4085 }
4086 if (startIndex >= array.length) {
4087 startIndex = array.length - 1;
4088 }
4089 for (int i = startIndex; i >= 0; i--) {
4090 if (valueToFind == array[i]) {
4091 return i;
4092 }
4093 }
4094 return INDEX_NOT_FOUND;
4095 }
4096
4097 /**
4098 * Finds the last index of the given value within the array.
4099 * <p>
4100 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4101 * </p>
4102 *
4103 * @param array the array to traverse backwards looking for the object, may be {@code null}
4104 * @param valueToFind the object to find
4105 * @return the last index of the value within the array,
4106 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4107 */
4108 public static int lastIndexOf(final int[] array, final int valueToFind) {
4109 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4110 }
4111
4112 /**
4113 * Finds the last index of the given value in the array starting at the given index.
4114 * <p>
4115 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4116 * </p>
4117 * <p>
4118 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
4119 * array length will search from the end of the array.
4120 * </p>
4121 *
4122 * @param array the array to traverse for looking for the object, may be {@code null}
4123 * @param valueToFind the value to find
4124 * @param startIndex the start index to traverse backwards from
4125 * @return the last index of the value within the array,
4126 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4127 */
4128 public static int lastIndexOf(final int[] array, final int valueToFind, int startIndex) {
4129 if (array == null || startIndex < 0) {
4130 return INDEX_NOT_FOUND;
4131 }
4132 if (startIndex >= array.length) {
4133 startIndex = array.length - 1;
4134 }
4135 for (int i = startIndex; i >= 0; i--) {
4136 if (valueToFind == array[i]) {
4137 return i;
4138 }
4139 }
4140 return INDEX_NOT_FOUND;
4141 }
4142
4143 /**
4144 * Finds the last index of the given value within the array.
4145 * <p>
4146 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4147 * </p>
4148 *
4149 * @param array the array to traverse backwards looking for the object, may be {@code null}
4150 * @param valueToFind the object to find
4151 * @return the last index of the value within the array,
4152 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4153 */
4154 public static int lastIndexOf(final long[] array, final long valueToFind) {
4155 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4156 }
4157
4158 /**
4159 * Finds the last index of the given value in the array starting at the given index.
4160 * <p>
4161 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4162 * </p>
4163 * <p>
4164 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
4165 * array length will search from the end of the array.
4166 * </p>
4167 *
4168 * @param array the array to traverse for looking for the object, may be {@code null}
4169 * @param valueToFind the value to find
4170 * @param startIndex the start index to traverse backwards from
4171 * @return the last index of the value within the array,
4172 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4173 */
4174 public static int lastIndexOf(final long[] array, final long valueToFind, int startIndex) {
4175 if (array == null || startIndex < 0) {
4176 return INDEX_NOT_FOUND;
4177 }
4178 if (startIndex >= array.length) {
4179 startIndex = array.length - 1;
4180 }
4181 for (int i = startIndex; i >= 0; i--) {
4182 if (valueToFind == array[i]) {
4183 return i;
4184 }
4185 }
4186 return INDEX_NOT_FOUND;
4187 }
4188
4189 /**
4190 * Finds the last index of the given object within the array.
4191 * <p>
4192 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4193 * </p>
4194 *
4195 * @param array the array to traverse backwards looking for the object, may be {@code null}
4196 * @param objectToFind the object to find, may be {@code null}
4197 * @return the last index of the object within the array,
4198 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4199 */
4200 public static int lastIndexOf(final Object[] array, final Object objectToFind) {
4201 return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
4202 }
4203
4204 /**
4205 * Finds the last index of the given object in the array starting at the given index.
4206 * <p>
4207 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4208 * </p>
4209 * <p>
4210 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
4211 * the array length will search from the end of the array.
4212 * </p>
4213 *
4214 * @param array the array to traverse for looking for the object, may be {@code null}
4215 * @param objectToFind the object to find, may be {@code null}
4216 * @param startIndex the start index to traverse backwards from
4217 * @return the last index of the object within the array,
4218 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4219 */
4220 public static int lastIndexOf(final Object[] array, final Object objectToFind, int startIndex) {
4221 if (array == null || startIndex < 0) {
4222 return INDEX_NOT_FOUND;
4223 }
4224 if (startIndex >= array.length) {
4225 startIndex = array.length - 1;
4226 }
4227 if (objectToFind == null) {
4228 for (int i = startIndex; i >= 0; i--) {
4229 if (array[i] == null) {
4230 return i;
4231 }
4232 }
4233 } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
4234 for (int i = startIndex; i >= 0; i--) {
4235 if (objectToFind.equals(array[i])) {
4236 return i;
4237 }
4238 }
4239 }
4240 return INDEX_NOT_FOUND;
4241 }
4242
4243 /**
4244 * Finds the last index of the given value within the array.
4245 * <p>
4246 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4247 * </p>
4248 *
4249 * @param array the array to traverse backwards looking for the object, may be {@code null}
4250 * @param valueToFind the object to find
4251 * @return the last index of the value within the array,
4252 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4253 */
4254 public static int lastIndexOf(final short[] array, final short valueToFind) {
4255 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4256 }
4257
4258 /**
4259 * Finds the last index of the given value in the array starting at the given index.
4260 * <p>
4261 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4262 * </p>
4263 * <p>
4264 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
4265 * array length will search from the end of the array.
4266 * </p>
4267 *
4268 * @param array the array to traverse for looking for the object, may be {@code null}
4269 * @param valueToFind the value to find
4270 * @param startIndex the start index to traverse backwards from
4271 * @return the last index of the value within the array,
4272 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
4273 */
4274 public static int lastIndexOf(final short[] array, final short valueToFind, int startIndex) {
4275 if (array == null || startIndex < 0) {
4276 return INDEX_NOT_FOUND;
4277 }
4278 if (startIndex >= array.length) {
4279 startIndex = array.length - 1;
4280 }
4281 for (int i = startIndex; i >= 0; i--) {
4282 if (valueToFind == array[i]) {
4283 return i;
4284 }
4285 }
4286 return INDEX_NOT_FOUND;
4287 }
4288
4289 /**
4290 * Maps elements from an array into elements of a new array of a given type, while mapping old elements to new elements.
4291 *
4292 * @param <T> The input array type.
4293 * @param <R> The output array type.
4294 * @param <E> The type of exceptions thrown when the mapper function fails.
4295 * @param array The input array.
4296 * @param componentType the component type of the result array.
4297 * @param mapper a non-interfering, stateless function to apply to each element
4298 * @return a new array
4299 * @throws E Thrown when the mapper function fails.
4300 */
4301 private static <T, R, E extends Throwable> R[] map(final T[] array, final Class<R> componentType, final FailableFunction<? super T, ? extends R, E> mapper)
4302 throws E {
4303 return ArrayFill.fill(newInstance(componentType, array.length), i -> mapper.apply(array[i]));
4304 }
4305
4306 private static int max0(final int other) {
4307 return Math.max(0, other);
4308 }
4309
4310 /**
4311 * Delegates to {@link Array#newInstance(Class,int)} using generics.
4312 *
4313 * @param <T> The array type.
4314 * @param componentType The array class.
4315 * @param length the array length
4316 * @return The new array.
4317 * @throws NullPointerException if the specified {@code componentType} parameter is null.
4318 * @since 3.13.0
4319 */
4320 @SuppressWarnings("unchecked") // OK, because array and values are of type T
4321 public static <T> T[] newInstance(final Class<T> componentType, final int length) {
4322 return (T[]) Array.newInstance(componentType, length);
4323 }
4324
4325 /**
4326 * Defensive programming technique to change a {@code null}
4327 * reference to an empty one.
4328 * <p>
4329 * This method returns a default array for a {@code null} input array.
4330 * </p>
4331 * <p>
4332 * As a memory optimizing technique an empty array passed in will be overridden with
4333 * the empty {@code public static} references in this class.
4334 * </p>
4335 *
4336 * @param <T> The array type.
4337 * @param array the array to check for {@code null} or empty
4338 * @param defaultArray A default array, usually empty.
4339 * @return the same array, or defaultArray if {@code null} or empty input.
4340 * @since 3.15.0
4341 */
4342 public static <T> T[] nullTo(final T[] array, final T[] defaultArray) {
4343 return isEmpty(array) ? defaultArray : array;
4344 }
4345
4346 /**
4347 * Defensive programming technique to change a {@code null}
4348 * reference to an empty one.
4349 * <p>
4350 * This method returns an empty array for a {@code null} input array.
4351 * </p>
4352 * <p>
4353 * As a memory optimizing technique an empty array passed in will be overridden with
4354 * the empty {@code public static} references in this class.
4355 * </p>
4356 *
4357 * @param array the array to check for {@code null} or empty
4358 * @return the same array, {@code public static} empty array if {@code null} or empty input
4359 * @since 2.5
4360 */
4361 public static boolean[] nullToEmpty(final boolean[] array) {
4362 return isEmpty(array) ? EMPTY_BOOLEAN_ARRAY : array;
4363 }
4364
4365 /**
4366 * Defensive programming technique to change a {@code null}
4367 * reference to an empty one.
4368 * <p>
4369 * This method returns an empty array for a {@code null} input array.
4370 * </p>
4371 * <p>
4372 * As a memory optimizing technique an empty array passed in will be overridden with
4373 * the empty {@code public static} references in this class.
4374 * </p>
4375 *
4376 * @param array the array to check for {@code null} or empty
4377 * @return the same array, {@code public static} empty array if {@code null} or empty input
4378 * @since 2.5
4379 */
4380 public static Boolean[] nullToEmpty(final Boolean[] array) {
4381 return nullTo(array, EMPTY_BOOLEAN_OBJECT_ARRAY);
4382 }
4383
4384 /**
4385 * Defensive programming technique to change a {@code null}
4386 * reference to an empty one.
4387 * <p>
4388 * This method returns an empty array for a {@code null} input array.
4389 * </p>
4390 * <p>
4391 * As a memory optimizing technique an empty array passed in will be overridden with
4392 * the empty {@code public static} references in this class.
4393 * </p>
4394 *
4395 * @param array the array to check for {@code null} or empty
4396 * @return the same array, {@code public static} empty array if {@code null} or empty input
4397 * @since 2.5
4398 */
4399 public static byte[] nullToEmpty(final byte[] array) {
4400 return isEmpty(array) ? EMPTY_BYTE_ARRAY : array;
4401 }
4402
4403 /**
4404 * Defensive programming technique to change a {@code null}
4405 * reference to an empty one.
4406 * <p>
4407 * This method returns an empty array for a {@code null} input array.
4408 * </p>
4409 * <p>
4410 * As a memory optimizing technique an empty array passed in will be overridden with
4411 * the empty {@code public static} references in this class.
4412 * </p>
4413 *
4414 * @param array the array to check for {@code null} or empty
4415 * @return the same array, {@code public static} empty array if {@code null} or empty input
4416 * @since 2.5
4417 */
4418 public static Byte[] nullToEmpty(final Byte[] array) {
4419 return nullTo(array, EMPTY_BYTE_OBJECT_ARRAY);
4420 }
4421
4422 /**
4423 * Defensive programming technique to change a {@code null}
4424 * reference to an empty one.
4425 * <p>
4426 * This method returns an empty array for a {@code null} input array.
4427 * </p>
4428 * <p>
4429 * As a memory optimizing technique an empty array passed in will be overridden with
4430 * the empty {@code public static} references in this class.
4431 * </p>
4432 *
4433 * @param array the array to check for {@code null} or empty
4434 * @return the same array, {@code public static} empty array if {@code null} or empty input
4435 * @since 2.5
4436 */
4437 public static char[] nullToEmpty(final char[] array) {
4438 return isEmpty(array) ? EMPTY_CHAR_ARRAY : array;
4439 }
4440
4441 /**
4442 * Defensive programming technique to change a {@code null}
4443 * reference to an empty one.
4444 * <p>
4445 * This method returns an empty array for a {@code null} input array.
4446 * </p>
4447 * <p>
4448 * As a memory optimizing technique an empty array passed in will be overridden with
4449 * the empty {@code public static} references in this class.
4450 * </p>
4451 *
4452 * @param array the array to check for {@code null} or empty
4453 * @return the same array, {@code public static} empty array if {@code null} or empty input
4454 * @since 2.5
4455 */
4456 public static Character[] nullToEmpty(final Character[] array) {
4457 return nullTo(array, EMPTY_CHARACTER_OBJECT_ARRAY);
4458 }
4459
4460 /**
4461 * Defensive programming technique to change a {@code null}
4462 * reference to an empty one.
4463 * <p>
4464 * This method returns an empty array for a {@code null} input array.
4465 * </p>
4466 * <p>
4467 * As a memory optimizing technique an empty array passed in will be overridden with
4468 * the empty {@code public static} references in this class.
4469 * </p>
4470 *
4471 * @param array the array to check for {@code null} or empty
4472 * @return the same array, {@code public static} empty array if {@code null} or empty input
4473 * @since 3.2
4474 */
4475 public static Class<?>[] nullToEmpty(final Class<?>[] array) {
4476 return nullTo(array, EMPTY_CLASS_ARRAY);
4477 }
4478
4479 /**
4480 * Defensive programming technique to change a {@code null}
4481 * reference to an empty one.
4482 * <p>
4483 * This method returns an empty array for a {@code null} input array.
4484 * </p>
4485 * <p>
4486 * As a memory optimizing technique an empty array passed in will be overridden with
4487 * the empty {@code public static} references in this class.
4488 * </p>
4489 *
4490 * @param array the array to check for {@code null} or empty
4491 * @return the same array, {@code public static} empty array if {@code null} or empty input
4492 * @since 2.5
4493 */
4494 public static double[] nullToEmpty(final double[] array) {
4495 return isEmpty(array) ? EMPTY_DOUBLE_ARRAY : array;
4496 }
4497
4498 /**
4499 * Defensive programming technique to change a {@code null}
4500 * reference to an empty one.
4501 * <p>
4502 * This method returns an empty array for a {@code null} input array.
4503 * </p>
4504 * <p>
4505 * As a memory optimizing technique an empty array passed in will be overridden with
4506 * the empty {@code public static} references in this class.
4507 * </p>
4508 *
4509 * @param array the array to check for {@code null} or empty
4510 * @return the same array, {@code public static} empty array if {@code null} or empty input
4511 * @since 2.5
4512 */
4513 public static Double[] nullToEmpty(final Double[] array) {
4514 return nullTo(array, EMPTY_DOUBLE_OBJECT_ARRAY);
4515 }
4516
4517 /**
4518 * Defensive programming technique to change a {@code null}
4519 * reference to an empty one.
4520 * <p>
4521 * This method returns an empty array for a {@code null} input array.
4522 * </p>
4523 * <p>
4524 * As a memory optimizing technique an empty array passed in will be overridden with
4525 * the empty {@code public static} references in this class.
4526 * </p>
4527 *
4528 * @param array the array to check for {@code null} or empty
4529 * @return the same array, {@code public static} empty array if {@code null} or empty input
4530 * @since 2.5
4531 */
4532 public static float[] nullToEmpty(final float[] array) {
4533 return isEmpty(array) ? EMPTY_FLOAT_ARRAY : array;
4534 }
4535
4536 /**
4537 * Defensive programming technique to change a {@code null}
4538 * reference to an empty one.
4539 * <p>
4540 * This method returns an empty array for a {@code null} input array.
4541 * </p>
4542 * <p>
4543 * As a memory optimizing technique an empty array passed in will be overridden with
4544 * the empty {@code public static} references in this class.
4545 * </p>
4546 *
4547 * @param array the array to check for {@code null} or empty
4548 * @return the same array, {@code public static} empty array if {@code null} or empty input
4549 * @since 2.5
4550 */
4551 public static Float[] nullToEmpty(final Float[] array) {
4552 return nullTo(array, EMPTY_FLOAT_OBJECT_ARRAY);
4553 }
4554
4555 /**
4556 * Defensive programming technique to change a {@code null}
4557 * reference to an empty one.
4558 * <p>
4559 * This method returns an empty array for a {@code null} input array.
4560 * </p>
4561 * <p>
4562 * As a memory optimizing technique an empty array passed in will be overridden with
4563 * the empty {@code public static} references in this class.
4564 * </p>
4565 *
4566 * @param array the array to check for {@code null} or empty
4567 * @return the same array, {@code public static} empty array if {@code null} or empty input
4568 * @since 2.5
4569 */
4570 public static int[] nullToEmpty(final int[] array) {
4571 return isEmpty(array) ? EMPTY_INT_ARRAY : array;
4572 }
4573
4574 /**
4575 * Defensive programming technique to change a {@code null}
4576 * reference to an empty one.
4577 * <p>
4578 * This method returns an empty array for a {@code null} input array.
4579 * </p>
4580 * <p>
4581 * As a memory optimizing technique an empty array passed in will be overridden with
4582 * the empty {@code public static} references in this class.
4583 * </p>
4584 *
4585 * @param array the array to check for {@code null} or empty
4586 * @return the same array, {@code public static} empty array if {@code null} or empty input
4587 * @since 2.5
4588 */
4589 public static Integer[] nullToEmpty(final Integer[] array) {
4590 return nullTo(array, EMPTY_INTEGER_OBJECT_ARRAY);
4591 }
4592
4593 /**
4594 * Defensive programming technique to change a {@code null}
4595 * reference to an empty one.
4596 * <p>
4597 * This method returns an empty array for a {@code null} input array.
4598 * </p>
4599 * <p>
4600 * As a memory optimizing technique an empty array passed in will be overridden with
4601 * the empty {@code public static} references in this class.
4602 * </p>
4603 *
4604 * @param array the array to check for {@code null} or empty
4605 * @return the same array, {@code public static} empty array if {@code null} or empty input
4606 * @since 2.5
4607 */
4608 public static long[] nullToEmpty(final long[] array) {
4609 return isEmpty(array) ? EMPTY_LONG_ARRAY : array;
4610 }
4611
4612 /**
4613 * Defensive programming technique to change a {@code null}
4614 * reference to an empty one.
4615 * <p>
4616 * This method returns an empty array for a {@code null} input array.
4617 * </p>
4618 * <p>
4619 * As a memory optimizing technique an empty array passed in will be overridden with
4620 * the empty {@code public static} references in this class.
4621 * </p>
4622 *
4623 * @param array the array to check for {@code null} or empty
4624 * @return the same array, {@code public static} empty array if {@code null} or empty input
4625 * @since 2.5
4626 */
4627 public static Long[] nullToEmpty(final Long[] array) {
4628 return nullTo(array, EMPTY_LONG_OBJECT_ARRAY);
4629 }
4630
4631 /**
4632 * Defensive programming technique to change a {@code null}
4633 * reference to an empty one.
4634 * <p>
4635 * This method returns an empty array for a {@code null} input array.
4636 * </p>
4637 * <p>
4638 * As a memory optimizing technique an empty array passed in will be overridden with
4639 * the empty {@code public static} references in this class.
4640 * </p>
4641 *
4642 * @param array the array to check for {@code null} or empty
4643 * @return the same array, {@code public static} empty array if {@code null} or empty input
4644 * @since 2.5
4645 */
4646 public static Object[] nullToEmpty(final Object[] array) {
4647 return nullTo(array, EMPTY_OBJECT_ARRAY);
4648 }
4649
4650 /**
4651 * Defensive programming technique to change a {@code null}
4652 * reference to an empty one.
4653 * <p>
4654 * This method returns an empty array for a {@code null} input array.
4655 * </p>
4656 * <p>
4657 * As a memory optimizing technique an empty array passed in will be overridden with
4658 * the empty {@code public static} references in this class.
4659 * </p>
4660 *
4661 * @param array the array to check for {@code null} or empty
4662 * @return the same array, {@code public static} empty array if {@code null} or empty input
4663 * @since 2.5
4664 */
4665 public static short[] nullToEmpty(final short[] array) {
4666 return isEmpty(array) ? EMPTY_SHORT_ARRAY : array;
4667 }
4668
4669 /**
4670 * Defensive programming technique to change a {@code null}
4671 * reference to an empty one.
4672 * <p>
4673 * This method returns an empty array for a {@code null} input array.
4674 * </p>
4675 * <p>
4676 * As a memory optimizing technique an empty array passed in will be overridden with
4677 * the empty {@code public static} references in this class.
4678 * </p>
4679 *
4680 * @param array the array to check for {@code null} or empty
4681 * @return the same array, {@code public static} empty array if {@code null} or empty input
4682 * @since 2.5
4683 */
4684 public static Short[] nullToEmpty(final Short[] array) {
4685 return nullTo(array, EMPTY_SHORT_OBJECT_ARRAY);
4686 }
4687
4688 /**
4689 * Defensive programming technique to change a {@code null}
4690 * reference to an empty one.
4691 * <p>
4692 * This method returns an empty array for a {@code null} input array.
4693 * </p>
4694 * <p>
4695 * As a memory optimizing technique an empty array passed in will be overridden with
4696 * the empty {@code public static} references in this class.
4697 * </p>
4698 *
4699 * @param array the array to check for {@code null} or empty
4700 * @return the same array, {@code public static} empty array if {@code null} or empty input
4701 * @since 2.5
4702 */
4703 public static String[] nullToEmpty(final String[] array) {
4704 return nullTo(array, EMPTY_STRING_ARRAY);
4705 }
4706
4707 /**
4708 * Defensive programming technique to change a {@code null}
4709 * reference to an empty one.
4710 * <p>
4711 * This method returns an empty array for a {@code null} input array.
4712 * </p>
4713 *
4714 * @param array the array to check for {@code null} or empty
4715 * @param type the class representation of the desired array
4716 * @param <T> the class type
4717 * @return the same array, {@code public static} empty array if {@code null}
4718 * @throws IllegalArgumentException if the type argument is null
4719 * @since 3.5
4720 */
4721 public static <T> T[] nullToEmpty(final T[] array, final Class<T[]> type) {
4722 if (type == null) {
4723 throw new IllegalArgumentException("The type must not be null");
4724 }
4725 if (array == null) {
4726 return type.cast(Array.newInstance(type.getComponentType(), 0));
4727 }
4728 return array;
4729 }
4730
4731 /**
4732 * Gets the {@link ThreadLocalRandom} for {@code shuffle} methods that don't take a {@link Random} argument.
4733 *
4734 * @return the current ThreadLocalRandom.
4735 */
4736 private static ThreadLocalRandom random() {
4737 return ThreadLocalRandom.current();
4738 }
4739
4740 /**
4741 * Removes the element at the specified position from the specified array.
4742 * All subsequent elements are shifted to the left (subtracts one from
4743 * their indices).
4744 * <p>
4745 * This method returns a new array with the same elements of the input
4746 * array except the element on the specified position. The component
4747 * type of the returned array is always the same as that of the input
4748 * array.
4749 * </p>
4750 * <p>
4751 * If the input array is {@code null}, an IndexOutOfBoundsException
4752 * will be thrown, because in that case no valid index can be specified.
4753 * </p>
4754 * <pre>
4755 * ArrayUtils.remove([true], 0) = []
4756 * ArrayUtils.remove([true, false], 0) = [false]
4757 * ArrayUtils.remove([true, false], 1) = [true]
4758 * ArrayUtils.remove([true, true, false], 1) = [true, false]
4759 * </pre>
4760 *
4761 * @param array the array to remove the element from, may not be {@code null}
4762 * @param index the position of the element to be removed
4763 * @return A new array containing the existing elements except the element
4764 * at the specified position.
4765 * @throws IndexOutOfBoundsException if the index is out of range
4766 * (index < 0 || index >= array.length), or if the array is {@code null}.
4767 * @since 2.1
4768 */
4769 public static boolean[] remove(final boolean[] array, final int index) {
4770 return (boolean[]) remove((Object) array, index);
4771 }
4772
4773 /**
4774 * Removes the element at the specified position from the specified array.
4775 * All subsequent elements are shifted to the left (subtracts one from
4776 * their indices).
4777 * <p>
4778 * This method returns a new array with the same elements of the input
4779 * array except the element on the specified position. The component
4780 * type of the returned array is always the same as that of the input
4781 * array.
4782 * </p>
4783 * <p>
4784 * If the input array is {@code null}, an IndexOutOfBoundsException
4785 * will be thrown, because in that case no valid index can be specified.
4786 * </p>
4787 * <pre>
4788 * ArrayUtils.remove([1], 0) = []
4789 * ArrayUtils.remove([1, 0], 0) = [0]
4790 * ArrayUtils.remove([1, 0], 1) = [1]
4791 * ArrayUtils.remove([1, 0, 1], 1) = [1, 1]
4792 * </pre>
4793 *
4794 * @param array the array to remove the element from, may not be {@code null}
4795 * @param index the position of the element to be removed
4796 * @return A new array containing the existing elements except the element
4797 * at the specified position.
4798 * @throws IndexOutOfBoundsException if the index is out of range
4799 * (index < 0 || index >= array.length), or if the array is {@code null}.
4800 * @since 2.1
4801 */
4802 public static byte[] remove(final byte[] array, final int index) {
4803 return (byte[]) remove((Object) array, index);
4804 }
4805
4806 /**
4807 * Removes the element at the specified position from the specified array.
4808 * All subsequent elements are shifted to the left (subtracts one from
4809 * their indices).
4810 * <p>
4811 * This method returns a new array with the same elements of the input
4812 * array except the element on the specified position. The component
4813 * type of the returned array is always the same as that of the input
4814 * array.
4815 * </p>
4816 * <p>
4817 * If the input array is {@code null}, an IndexOutOfBoundsException
4818 * will be thrown, because in that case no valid index can be specified.
4819 * </p>
4820 * <pre>
4821 * ArrayUtils.remove(['a'], 0) = []
4822 * ArrayUtils.remove(['a', 'b'], 0) = ['b']
4823 * ArrayUtils.remove(['a', 'b'], 1) = ['a']
4824 * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
4825 * </pre>
4826 *
4827 * @param array the array to remove the element from, may not be {@code null}
4828 * @param index the position of the element to be removed
4829 * @return A new array containing the existing elements except the element
4830 * at the specified position.
4831 * @throws IndexOutOfBoundsException if the index is out of range
4832 * (index < 0 || index >= array.length), or if the array is {@code null}.
4833 * @since 2.1
4834 */
4835 public static char[] remove(final char[] array, final int index) {
4836 return (char[]) remove((Object) array, index);
4837 }
4838
4839 /**
4840 * Removes the element at the specified position from the specified array.
4841 * All subsequent elements are shifted to the left (subtracts one from
4842 * their indices).
4843 * <p>
4844 * This method returns a new array with the same elements of the input
4845 * array except the element on the specified position. The component
4846 * type of the returned array is always the same as that of the input
4847 * array.
4848 * </p>
4849 * <p>
4850 * If the input array is {@code null}, an IndexOutOfBoundsException
4851 * will be thrown, because in that case no valid index can be specified.
4852 * </p>
4853 * <pre>
4854 * ArrayUtils.remove([1.1], 0) = []
4855 * ArrayUtils.remove([2.5, 6.0], 0) = [6.0]
4856 * ArrayUtils.remove([2.5, 6.0], 1) = [2.5]
4857 * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4858 * </pre>
4859 *
4860 * @param array the array to remove the element from, may not be {@code null}
4861 * @param index the position of the element to be removed
4862 * @return A new array containing the existing elements except the element
4863 * at the specified position.
4864 * @throws IndexOutOfBoundsException if the index is out of range
4865 * (index < 0 || index >= array.length), or if the array is {@code null}.
4866 * @since 2.1
4867 */
4868 public static double[] remove(final double[] array, final int index) {
4869 return (double[]) remove((Object) array, index);
4870 }
4871
4872 /**
4873 * Removes the element at the specified position from the specified array.
4874 * All subsequent elements are shifted to the left (subtracts one from
4875 * their indices).
4876 * <p>
4877 * This method returns a new array with the same elements of the input
4878 * array except the element on the specified position. The component
4879 * type of the returned array is always the same as that of the input
4880 * array.
4881 * </p>
4882 * <p>
4883 * If the input array is {@code null}, an IndexOutOfBoundsException
4884 * will be thrown, because in that case no valid index can be specified.
4885 * </p>
4886 * <pre>
4887 * ArrayUtils.remove([1.1], 0) = []
4888 * ArrayUtils.remove([2.5, 6.0], 0) = [6.0]
4889 * ArrayUtils.remove([2.5, 6.0], 1) = [2.5]
4890 * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4891 * </pre>
4892 *
4893 * @param array the array to remove the element from, may not be {@code null}
4894 * @param index the position of the element to be removed
4895 * @return A new array containing the existing elements except the element
4896 * at the specified position.
4897 * @throws IndexOutOfBoundsException if the index is out of range
4898 * (index < 0 || index >= array.length), or if the array is {@code null}.
4899 * @since 2.1
4900 */
4901 public static float[] remove(final float[] array, final int index) {
4902 return (float[]) remove((Object) array, index);
4903 }
4904
4905 /**
4906 * Removes the element at the specified position from the specified array.
4907 * All subsequent elements are shifted to the left (subtracts one from
4908 * their indices).
4909 * <p>
4910 * This method returns a new array with the same elements of the input
4911 * array except the element on the specified position. The component
4912 * type of the returned array is always the same as that of the input
4913 * array.
4914 * </p>
4915 * <p>
4916 * If the input array is {@code null}, an IndexOutOfBoundsException
4917 * will be thrown, because in that case no valid index can be specified.
4918 * </p>
4919 * <pre>
4920 * ArrayUtils.remove([1], 0) = []
4921 * ArrayUtils.remove([2, 6], 0) = [6]
4922 * ArrayUtils.remove([2, 6], 1) = [2]
4923 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
4924 * </pre>
4925 *
4926 * @param array the array to remove the element from, may not be {@code null}
4927 * @param index the position of the element to be removed
4928 * @return A new array containing the existing elements except the element
4929 * at the specified position.
4930 * @throws IndexOutOfBoundsException if the index is out of range
4931 * (index < 0 || index >= array.length), or if the array is {@code null}.
4932 * @since 2.1
4933 */
4934 public static int[] remove(final int[] array, final int index) {
4935 return (int[]) remove((Object) array, index);
4936 }
4937
4938 /**
4939 * Removes the element at the specified position from the specified array.
4940 * All subsequent elements are shifted to the left (subtracts one from
4941 * their indices).
4942 * <p>
4943 * This method returns a new array with the same elements of the input
4944 * array except the element on the specified position. The component
4945 * type of the returned array is always the same as that of the input
4946 * array.
4947 * </p>
4948 * <p>
4949 * If the input array is {@code null}, an IndexOutOfBoundsException
4950 * will be thrown, because in that case no valid index can be specified.
4951 * </p>
4952 * <pre>
4953 * ArrayUtils.remove([1], 0) = []
4954 * ArrayUtils.remove([2, 6], 0) = [6]
4955 * ArrayUtils.remove([2, 6], 1) = [2]
4956 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
4957 * </pre>
4958 *
4959 * @param array the array to remove the element from, may not be {@code null}
4960 * @param index the position of the element to be removed
4961 * @return A new array containing the existing elements except the element
4962 * at the specified position.
4963 * @throws IndexOutOfBoundsException if the index is out of range
4964 * (index < 0 || index >= array.length), or if the array is {@code null}.
4965 * @since 2.1
4966 */
4967 public static long[] remove(final long[] array, final int index) {
4968 return (long[]) remove((Object) array, index);
4969 }
4970
4971 /**
4972 * Removes the element at the specified position from the specified array.
4973 * All subsequent elements are shifted to the left (subtracts one from
4974 * their indices).
4975 * <p>
4976 * This method returns a new array with the same elements of the input
4977 * array except the element on the specified position. The component
4978 * type of the returned array is always the same as that of the input
4979 * array.
4980 * </p>
4981 * <p>
4982 * If the input array is {@code null}, an IndexOutOfBoundsException
4983 * will be thrown, because in that case no valid index can be specified.
4984 * </p>
4985 *
4986 * @param array the array to remove the element from, may not be {@code null}
4987 * @param index the position of the element to be removed
4988 * @return A new array containing the existing elements except the element
4989 * at the specified position.
4990 * @throws IndexOutOfBoundsException if the index is out of range
4991 * (index < 0 || index >= array.length), or if the array is {@code null}.
4992 * @since 2.1
4993 */
4994 private static Object remove(final Object array, final int index) {
4995 final int length = getLength(array);
4996 if (index < 0 || index >= length) {
4997 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
4998 }
4999 final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
5000 System.arraycopy(array, 0, result, 0, index);
5001 if (index < length - 1) {
5002 System.arraycopy(array, index + 1, result, index, length - index - 1);
5003 }
5004 return result;
5005 }
5006
5007 /**
5008 * Removes the element at the specified position from the specified array.
5009 * All subsequent elements are shifted to the left (subtracts one from
5010 * their indices).
5011 * <p>
5012 * This method returns a new array with the same elements of the input
5013 * array except the element on the specified position. The component
5014 * type of the returned array is always the same as that of the input
5015 * array.
5016 * </p>
5017 * <p>
5018 * If the input array is {@code null}, an IndexOutOfBoundsException
5019 * will be thrown, because in that case no valid index can be specified.
5020 * </p>
5021 * <pre>
5022 * ArrayUtils.remove([1], 0) = []
5023 * ArrayUtils.remove([2, 6], 0) = [6]
5024 * ArrayUtils.remove([2, 6], 1) = [2]
5025 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
5026 * </pre>
5027 *
5028 * @param array the array to remove the element from, may not be {@code null}
5029 * @param index the position of the element to be removed
5030 * @return A new array containing the existing elements except the element
5031 * at the specified position.
5032 * @throws IndexOutOfBoundsException if the index is out of range
5033 * (index < 0 || index >= array.length), or if the array is {@code null}.
5034 * @since 2.1
5035 */
5036 public static short[] remove(final short[] array, final int index) {
5037 return (short[]) remove((Object) array, index);
5038 }
5039
5040 /**
5041 * Removes the element at the specified position from the specified array.
5042 * All subsequent elements are shifted to the left (subtracts one from
5043 * their indices).
5044 * <p>
5045 * This method returns a new array with the same elements of the input
5046 * array except the element on the specified position. The component
5047 * type of the returned array is always the same as that of the input
5048 * array.
5049 * </p>
5050 * <p>
5051 * If the input array is {@code null}, an IndexOutOfBoundsException
5052 * will be thrown, because in that case no valid index can be specified.
5053 * </p>
5054 * <pre>
5055 * ArrayUtils.remove(["a"], 0) = []
5056 * ArrayUtils.remove(["a", "b"], 0) = ["b"]
5057 * ArrayUtils.remove(["a", "b"], 1) = ["a"]
5058 * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
5059 * </pre>
5060 *
5061 * @param <T> the component type of the array
5062 * @param array the array to remove the element from, may not be {@code null}
5063 * @param index the position of the element to be removed
5064 * @return A new array containing the existing elements except the element
5065 * at the specified position.
5066 * @throws IndexOutOfBoundsException if the index is out of range
5067 * (index < 0 || index >= array.length), or if the array is {@code null}.
5068 * @since 2.1
5069 */
5070 @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
5071 public static <T> T[] remove(final T[] array, final int index) {
5072 return (T[]) remove((Object) array, index);
5073 }
5074
5075 /**
5076 * Removes the elements at the specified positions from the specified array.
5077 * All remaining elements are shifted to the left.
5078 * <p>
5079 * This method returns a new array with the same elements of the input
5080 * array except those at the specified positions. The component
5081 * type of the returned array is always the same as that of the input
5082 * array.
5083 * </p>
5084 * <p>
5085 * If the input array is {@code null}, an IndexOutOfBoundsException
5086 * will be thrown, because in that case no valid index can be specified.
5087 * </p>
5088 * <pre>
5089 * ArrayUtils.removeAll([true, false, true], 0, 2) = [false]
5090 * ArrayUtils.removeAll([true, false, true], 1, 2) = [true]
5091 * </pre>
5092 *
5093 * @param array the array to remove the element from, may not be {@code null}
5094 * @param indices the positions of the elements to be removed
5095 * @return A new array containing the existing elements except those
5096 * at the specified positions.
5097 * @throws IndexOutOfBoundsException if any index is out of range
5098 * (index < 0 || index >= array.length), or if the array is {@code null}.
5099 * @since 3.0.1
5100 */
5101 public static boolean[] removeAll(final boolean[] array, final int... indices) {
5102 return (boolean[]) removeAll((Object) array, indices);
5103 }
5104
5105 /**
5106 * Removes the elements at the specified positions from the specified array.
5107 * All remaining elements are shifted to the left.
5108 * <p>
5109 * This method returns a new array with the same elements of the input
5110 * array except those at the specified positions. The component
5111 * type of the returned array is always the same as that of the input
5112 * array.
5113 * </p>
5114 * <p>
5115 * If the input array is {@code null}, an IndexOutOfBoundsException
5116 * will be thrown, because in that case no valid index can be specified.
5117 * </p>
5118 * <pre>
5119 * ArrayUtils.removeAll([1], 0) = []
5120 * ArrayUtils.removeAll([2, 6], 0) = [6]
5121 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5122 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5123 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5124 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5125 * </pre>
5126 *
5127 * @param array the array to remove the element from, may not be {@code null}
5128 * @param indices the positions of the elements to be removed
5129 * @return A new array containing the existing elements except those
5130 * at the specified positions.
5131 * @throws IndexOutOfBoundsException if any index is out of range
5132 * (index < 0 || index >= array.length), or if the array is {@code null}.
5133 * @since 3.0.1
5134 */
5135 public static byte[] removeAll(final byte[] array, final int... indices) {
5136 return (byte[]) removeAll((Object) array, indices);
5137 }
5138
5139 /**
5140 * Removes the elements at the specified positions from the specified array.
5141 * All remaining elements are shifted to the left.
5142 * <p>
5143 * This method returns a new array with the same elements of the input
5144 * array except those at the specified positions. The component
5145 * type of the returned array is always the same as that of the input
5146 * array.
5147 * </p>
5148 * <p>
5149 * If the input array is {@code null}, an IndexOutOfBoundsException
5150 * will be thrown, because in that case no valid index can be specified.
5151 * </p>
5152 * <pre>
5153 * ArrayUtils.removeAll([1], 0) = []
5154 * ArrayUtils.removeAll([2, 6], 0) = [6]
5155 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5156 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5157 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5158 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5159 * </pre>
5160 *
5161 * @param array the array to remove the element from, may not be {@code null}
5162 * @param indices the positions of the elements to be removed
5163 * @return A new array containing the existing elements except those
5164 * at the specified positions.
5165 * @throws IndexOutOfBoundsException if any index is out of range
5166 * (index < 0 || index >= array.length), or if the array is {@code null}.
5167 * @since 3.0.1
5168 */
5169 public static char[] removeAll(final char[] array, final int... indices) {
5170 return (char[]) removeAll((Object) array, indices);
5171 }
5172
5173 /**
5174 * Removes the elements at the specified positions from the specified array.
5175 * All remaining elements are shifted to the left.
5176 * <p>
5177 * This method returns a new array with the same elements of the input
5178 * array except those at the specified positions. The component
5179 * type of the returned array is always the same as that of the input
5180 * array.
5181 * </p>
5182 * <p>
5183 * If the input array is {@code null}, an IndexOutOfBoundsException
5184 * will be thrown, because in that case no valid index can be specified.
5185 * </p>
5186 * <pre>
5187 * ArrayUtils.removeAll([1], 0) = []
5188 * ArrayUtils.removeAll([2, 6], 0) = [6]
5189 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5190 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5191 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5192 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5193 * </pre>
5194 *
5195 * @param array the array to remove the element from, may not be {@code null}
5196 * @param indices the positions of the elements to be removed
5197 * @return A new array containing the existing elements except those
5198 * at the specified positions.
5199 * @throws IndexOutOfBoundsException if any index is out of range
5200 * (index < 0 || index >= array.length), or if the array is {@code null}.
5201 * @since 3.0.1
5202 */
5203 public static double[] removeAll(final double[] array, final int... indices) {
5204 return (double[]) removeAll((Object) array, indices);
5205 }
5206
5207 /**
5208 * Removes the elements at the specified positions from the specified array.
5209 * All remaining elements are shifted to the left.
5210 * <p>
5211 * This method returns a new array with the same elements of the input
5212 * array except those at the specified positions. The component
5213 * type of the returned array is always the same as that of the input
5214 * array.
5215 * </p>
5216 * <p>
5217 * If the input array is {@code null}, an IndexOutOfBoundsException
5218 * will be thrown, because in that case no valid index can be specified.
5219 * </p>
5220 * <pre>
5221 * ArrayUtils.removeAll([1], 0) = []
5222 * ArrayUtils.removeAll([2, 6], 0) = [6]
5223 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5224 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5225 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5226 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5227 * </pre>
5228 *
5229 * @param array the array to remove the element from, may not be {@code null}
5230 * @param indices the positions of the elements to be removed
5231 * @return A new array containing the existing elements except those
5232 * at the specified positions.
5233 * @throws IndexOutOfBoundsException if any index is out of range
5234 * (index < 0 || index >= array.length), or if the array is {@code null}.
5235 * @since 3.0.1
5236 */
5237 public static float[] removeAll(final float[] array, final int... indices) {
5238 return (float[]) removeAll((Object) array, indices);
5239 }
5240
5241 /**
5242 * Removes the elements at the specified positions from the specified array.
5243 * All remaining elements are shifted to the left.
5244 * <p>
5245 * This method returns a new array with the same elements of the input
5246 * array except those at the specified positions. The component
5247 * type of the returned array is always the same as that of the input
5248 * array.
5249 * </p>
5250 * <p>
5251 * If the input array is {@code null}, an IndexOutOfBoundsException
5252 * will be thrown, because in that case no valid index can be specified.
5253 * </p>
5254 * <pre>
5255 * ArrayUtils.removeAll([1], 0) = []
5256 * ArrayUtils.removeAll([2, 6], 0) = [6]
5257 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5258 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5259 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5260 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5261 * </pre>
5262 *
5263 * @param array the array to remove the element from, may not be {@code null}
5264 * @param indices the positions of the elements to be removed
5265 * @return A new array containing the existing elements except those
5266 * at the specified positions.
5267 * @throws IndexOutOfBoundsException if any index is out of range
5268 * (index < 0 || index >= array.length), or if the array is {@code null}.
5269 * @since 3.0.1
5270 */
5271 public static int[] removeAll(final int[] array, final int... indices) {
5272 return (int[]) removeAll((Object) array, indices);
5273 }
5274
5275 /**
5276 * Removes the elements at the specified positions from the specified array.
5277 * All remaining elements are shifted to the left.
5278 * <p>
5279 * This method returns a new array with the same elements of the input
5280 * array except those at the specified positions. The component
5281 * type of the returned array is always the same as that of the input
5282 * array.
5283 * </p>
5284 * <p>
5285 * If the input array is {@code null}, an IndexOutOfBoundsException
5286 * will be thrown, because in that case no valid index can be specified.
5287 * </p>
5288 * <pre>
5289 * ArrayUtils.removeAll([1], 0) = []
5290 * ArrayUtils.removeAll([2, 6], 0) = [6]
5291 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5292 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5293 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5294 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5295 * </pre>
5296 *
5297 * @param array the array to remove the element from, may not be {@code null}
5298 * @param indices the positions of the elements to be removed
5299 * @return A new array containing the existing elements except those
5300 * at the specified positions.
5301 * @throws IndexOutOfBoundsException if any index is out of range
5302 * (index < 0 || index >= array.length), or if the array is {@code null}.
5303 * @since 3.0.1
5304 */
5305 public static long[] removeAll(final long[] array, final int... indices) {
5306 return (long[]) removeAll((Object) array, indices);
5307 }
5308
5309 /**
5310 * Removes multiple array elements specified by index.
5311 *
5312 * @param array source
5313 * @param indices to remove
5314 * @return new array of same type minus elements specified by unique values of {@code indices}
5315 */
5316 // package protected for access by unit tests
5317 static Object removeAll(final Object array, final int... indices) {
5318 if (array == null) {
5319 return null;
5320 }
5321 final int length = getLength(array);
5322 int diff = 0; // number of distinct indexes, i.e. number of entries that will be removed
5323 final int[] clonedIndices = ArraySorter.sort(clone(indices));
5324 // identify length of result array
5325 if (isNotEmpty(clonedIndices)) {
5326 int i = clonedIndices.length;
5327 int prevIndex = length;
5328 while (--i >= 0) {
5329 final int index = clonedIndices[i];
5330 if (index < 0 || index >= length) {
5331 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
5332 }
5333 if (index >= prevIndex) {
5334 continue;
5335 }
5336 diff++;
5337 prevIndex = index;
5338 }
5339 }
5340 // create result array
5341 final Object result = Array.newInstance(array.getClass().getComponentType(), length - diff);
5342 if (diff < length && clonedIndices != null) {
5343 int end = length; // index just after last copy
5344 int dest = length - diff; // number of entries so far not copied
5345 for (int i = clonedIndices.length - 1; i >= 0; i--) {
5346 final int index = clonedIndices[i];
5347 if (end - index > 1) { // same as (cp > 0)
5348 final int cp = end - index - 1;
5349 dest -= cp;
5350 System.arraycopy(array, index + 1, result, dest, cp);
5351 // After this copy, we still have room for dest items.
5352 }
5353 end = index;
5354 }
5355 if (end > 0) {
5356 System.arraycopy(array, 0, result, 0, end);
5357 }
5358 }
5359 return result;
5360 }
5361
5362 /**
5363 * Removes the elements at the specified positions from the specified array.
5364 * All remaining elements are shifted to the left.
5365 * <p>
5366 * This method returns a new array with the same elements of the input
5367 * array except those at the specified positions. The component
5368 * type of the returned array is always the same as that of the input
5369 * array.
5370 * </p>
5371 * <p>
5372 * If the input array is {@code null}, an IndexOutOfBoundsException
5373 * will be thrown, because in that case no valid index can be specified.
5374 * </p>
5375 * <pre>
5376 * ArrayUtils.removeAll([1], 0) = []
5377 * ArrayUtils.removeAll([2, 6], 0) = [6]
5378 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5379 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5380 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5381 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5382 * </pre>
5383 *
5384 * @param array the array to remove the element from, may not be {@code null}
5385 * @param indices the positions of the elements to be removed
5386 * @return A new array containing the existing elements except those
5387 * at the specified positions.
5388 * @throws IndexOutOfBoundsException if any index is out of range
5389 * (index < 0 || index >= array.length), or if the array is {@code null}.
5390 * @since 3.0.1
5391 */
5392 public static short[] removeAll(final short[] array, final int... indices) {
5393 return (short[]) removeAll((Object) array, indices);
5394 }
5395
5396 /**
5397 * Removes the elements at the specified positions from the specified array.
5398 * All remaining elements are shifted to the left.
5399 * <p>
5400 * This method returns a new array with the same elements of the input
5401 * array except those at the specified positions. The component
5402 * type of the returned array is always the same as that of the input
5403 * array.
5404 * </p>
5405 * <p>
5406 * If the input array is {@code null}, an IndexOutOfBoundsException
5407 * will be thrown, because in that case no valid index can be specified.
5408 * </p>
5409 * <pre>
5410 * ArrayUtils.removeAll(["a", "b", "c"], 0, 2) = ["b"]
5411 * ArrayUtils.removeAll(["a", "b", "c"], 1, 2) = ["a"]
5412 * </pre>
5413 *
5414 * @param <T> the component type of the array
5415 * @param array the array to remove the element from, may not be {@code null}
5416 * @param indices the positions of the elements to be removed
5417 * @return A new array containing the existing elements except those
5418 * at the specified positions.
5419 * @throws IndexOutOfBoundsException if any index is out of range
5420 * (index < 0 || index >= array.length), or if the array is {@code null}.
5421 * @since 3.0.1
5422 */
5423 @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
5424 public static <T> T[] removeAll(final T[] array, final int... indices) {
5425 return (T[]) removeAll((Object) array, indices);
5426 }
5427
5428 /**
5429 * Removes the occurrences of the specified element from the specified boolean array.
5430 * <p>
5431 * All subsequent elements are shifted to the left (subtracts one from their indices).
5432 * If the array doesn't contain such an element, no elements are removed from the array.
5433 * {@code null} will be returned if the input array is {@code null}.
5434 * </p>
5435 *
5436 * @param array the input array, will not be modified, and may be {@code null}.
5437 * @param element the element to remove.
5438 * @return A new array containing the existing elements except the occurrences of the specified element.
5439 * @since 3.5
5440 * @deprecated Use {@link #removeAllOccurrences(boolean[], boolean)}.
5441 */
5442 @Deprecated
5443 public static boolean[] removeAllOccurences(final boolean[] array, final boolean element) {
5444 return (boolean[]) removeAt(array, indexesOf(array, element));
5445 }
5446
5447 /**
5448 * Removes the occurrences of the specified element from the specified byte array.
5449 * <p>
5450 * All subsequent elements are shifted to the left (subtracts one from their indices).
5451 * If the array doesn't contain such an element, no elements are removed from the array.
5452 * {@code null} will be returned if the input array is {@code null}.
5453 * </p>
5454 *
5455 * @param array the input array, will not be modified, and may be {@code null}.
5456 * @param element the element to remove.
5457 * @return A new array containing the existing elements except the occurrences of the specified element.
5458 * @since 3.5
5459 * @deprecated Use {@link #removeAllOccurrences(byte[], byte)}.
5460 */
5461 @Deprecated
5462 public static byte[] removeAllOccurences(final byte[] array, final byte element) {
5463 return (byte[]) removeAt(array, indexesOf(array, element));
5464 }
5465
5466 /**
5467 * Removes the occurrences of the specified element from the specified char array.
5468 * <p>
5469 * All subsequent elements are shifted to the left (subtracts one from their indices).
5470 * If the array doesn't contain such an element, no elements are removed from the array.
5471 * {@code null} will be returned if the input array is {@code null}.
5472 * </p>
5473 *
5474 * @param array the input array, will not be modified, and may be {@code null}.
5475 * @param element the element to remove.
5476 * @return A new array containing the existing elements except the occurrences of the specified element.
5477 * @since 3.5
5478 * @deprecated Use {@link #removeAllOccurrences(char[], char)}.
5479 */
5480 @Deprecated
5481 public static char[] removeAllOccurences(final char[] array, final char element) {
5482 return (char[]) removeAt(array, indexesOf(array, element));
5483 }
5484
5485 /**
5486 * Removes the occurrences of the specified element from the specified double array.
5487 * <p>
5488 * All subsequent elements are shifted to the left (subtracts one from their indices).
5489 * If the array doesn't contain such an element, no elements are removed from the array.
5490 * {@code null} will be returned if the input array is {@code null}.
5491 * </p>
5492 *
5493 * @param array the input array, will not be modified, and may be {@code null}.
5494 * @param element the element to remove.
5495 * @return A new array containing the existing elements except the occurrences of the specified element.
5496 * @since 3.5
5497 * @deprecated Use {@link #removeAllOccurrences(double[], double)}.
5498 */
5499 @Deprecated
5500 public static double[] removeAllOccurences(final double[] array, final double element) {
5501 return (double[]) removeAt(array, indexesOf(array, element));
5502 }
5503
5504 /**
5505 * Removes the occurrences of the specified element from the specified float array.
5506 * <p>
5507 * All subsequent elements are shifted to the left (subtracts one from their indices).
5508 * If the array doesn't contain such an element, no elements are removed from the array.
5509 * {@code null} will be returned if the input array is {@code null}.
5510 * </p>
5511 *
5512 * @param array the input array, will not be modified, and may be {@code null}.
5513 * @param element the element to remove.
5514 * @return A new array containing the existing elements except the occurrences of the specified element.
5515 * @since 3.5
5516 * @deprecated Use {@link #removeAllOccurrences(float[], float)}.
5517 */
5518 @Deprecated
5519 public static float[] removeAllOccurences(final float[] array, final float element) {
5520 return (float[]) removeAt(array, indexesOf(array, element));
5521 }
5522
5523 /**
5524 * Removes the occurrences of the specified element from the specified int array.
5525 * <p>
5526 * All subsequent elements are shifted to the left (subtracts one from their indices).
5527 * If the array doesn't contain such an element, no elements are removed from the array.
5528 * {@code null} will be returned if the input array is {@code null}.
5529 * </p>
5530 *
5531 * @param array the input array, will not be modified, and may be {@code null}.
5532 * @param element the element to remove.
5533 * @return A new array containing the existing elements except the occurrences of the specified element.
5534 * @since 3.5
5535 * @deprecated Use {@link #removeAllOccurrences(int[], int)}.
5536 */
5537 @Deprecated
5538 public static int[] removeAllOccurences(final int[] array, final int element) {
5539 return (int[]) removeAt(array, indexesOf(array, element));
5540 }
5541
5542 /**
5543 * Removes the occurrences of the specified element from the specified long array.
5544 * <p>
5545 * All subsequent elements are shifted to the left (subtracts one from their indices).
5546 * If the array doesn't contain such an element, no elements are removed from the array.
5547 * {@code null} will be returned if the input array is {@code null}.
5548 * </p>
5549 *
5550 * @param array the input array, will not be modified, and may be {@code null}.
5551 * @param element the element to remove.
5552 * @return A new array containing the existing elements except the occurrences of the specified element.
5553 * @since 3.5
5554 * @deprecated Use {@link #removeAllOccurrences(long[], long)}.
5555 */
5556 @Deprecated
5557 public static long[] removeAllOccurences(final long[] array, final long element) {
5558 return (long[]) removeAt(array, indexesOf(array, element));
5559 }
5560
5561 /**
5562 * Removes the occurrences of the specified element from the specified short array.
5563 * <p>
5564 * All subsequent elements are shifted to the left (subtracts one from their indices).
5565 * If the array doesn't contain such an element, no elements are removed from the array.
5566 * {@code null} will be returned if the input array is {@code null}.
5567 * </p>
5568 *
5569 * @param array the input array, will not be modified, and may be {@code null}.
5570 * @param element the element to remove.
5571 * @return A new array containing the existing elements except the occurrences of the specified element.
5572 * @since 3.5
5573 * @deprecated Use {@link #removeAllOccurrences(short[], short)}.
5574 */
5575 @Deprecated
5576 public static short[] removeAllOccurences(final short[] array, final short element) {
5577 return (short[]) removeAt(array, indexesOf(array, element));
5578 }
5579
5580 /**
5581 * Removes the occurrences of the specified element from the specified array.
5582 * <p>
5583 * All subsequent elements are shifted to the left (subtracts one from their indices).
5584 * If the array doesn't contain such an element, no elements are removed from the array.
5585 * {@code null} will be returned if the input array is {@code null}.
5586 * </p>
5587 *
5588 * @param <T> the type of object in the array, may be {@code null}.
5589 * @param array the input array, will not be modified, and may be {@code null}.
5590 * @param element the element to remove, may be {@code null}.
5591 * @return A new array containing the existing elements except the occurrences of the specified element.
5592 * @since 3.5
5593 * @deprecated Use {@link #removeAllOccurrences(Object[], Object)}.
5594 */
5595 @Deprecated
5596 public static <T> T[] removeAllOccurences(final T[] array, final T element) {
5597 return (T[]) removeAt(array, indexesOf(array, element));
5598 }
5599
5600 /**
5601 * Removes the occurrences of the specified element from the specified boolean array.
5602 * <p>
5603 * All subsequent elements are shifted to the left (subtracts one from their indices).
5604 * If the array doesn't contain such an element, no elements are removed from the array.
5605 * {@code null} will be returned if the input array is {@code null}.
5606 * </p>
5607 *
5608 * @param array the input array, will not be modified, and may be {@code null}.
5609 * @param element the element to remove.
5610 * @return A new array containing the existing elements except the occurrences of the specified element.
5611 * @since 3.10
5612 */
5613 public static boolean[] removeAllOccurrences(final boolean[] array, final boolean element) {
5614 return (boolean[]) removeAt(array, indexesOf(array, element));
5615 }
5616
5617 /**
5618 * Removes the occurrences of the specified element from the specified byte array.
5619 * <p>
5620 * All subsequent elements are shifted to the left (subtracts one from their indices).
5621 * If the array doesn't contain such an element, no elements are removed from the array.
5622 * {@code null} will be returned if the input array is {@code null}.
5623 * </p>
5624 *
5625 * @param array the input array, will not be modified, and may be {@code null}.
5626 * @param element the element to remove.
5627 * @return A new array containing the existing elements except the occurrences of the specified element.
5628 * @since 3.10
5629 */
5630 public static byte[] removeAllOccurrences(final byte[] array, final byte element) {
5631 return (byte[]) removeAt(array, indexesOf(array, element));
5632 }
5633
5634 /**
5635 * Removes the occurrences of the specified element from the specified char array.
5636 * <p>
5637 * All subsequent elements are shifted to the left (subtracts one from their indices).
5638 * If the array doesn't contain such an element, no elements are removed from the array.
5639 * {@code null} will be returned if the input array is {@code null}.
5640 * </p>
5641 *
5642 * @param array the input array, will not be modified, and may be {@code null}.
5643 * @param element the element to remove.
5644 * @return A new array containing the existing elements except the occurrences of the specified element.
5645 * @since 3.10
5646 */
5647 public static char[] removeAllOccurrences(final char[] array, final char element) {
5648 return (char[]) removeAt(array, indexesOf(array, element));
5649 }
5650
5651 /**
5652 * Removes the occurrences of the specified element from the specified double array.
5653 * <p>
5654 * All subsequent elements are shifted to the left (subtracts one from their indices).
5655 * If the array doesn't contain such an element, no elements are removed from the array.
5656 * {@code null} will be returned if the input array is {@code null}.
5657 * </p>
5658 *
5659 * @param array the input array, will not be modified, and may be {@code null}.
5660 * @param element the element to remove.
5661 * @return A new array containing the existing elements except the occurrences of the specified element.
5662 * @since 3.10
5663 */
5664 public static double[] removeAllOccurrences(final double[] array, final double element) {
5665 return (double[]) removeAt(array, indexesOf(array, element));
5666 }
5667
5668 /**
5669 * Removes the occurrences of the specified element from the specified float array.
5670 * <p>
5671 * All subsequent elements are shifted to the left (subtracts one from their indices).
5672 * If the array doesn't contain such an element, no elements are removed from the array.
5673 * {@code null} will be returned if the input array is {@code null}.
5674 * </p>
5675 *
5676 * @param array the input array, will not be modified, and may be {@code null}.
5677 * @param element the element to remove.
5678 * @return A new array containing the existing elements except the occurrences of the specified element.
5679 * @since 3.10
5680 */
5681 public static float[] removeAllOccurrences(final float[] array, final float element) {
5682 return (float[]) removeAt(array, indexesOf(array, element));
5683 }
5684
5685 /**
5686 * Removes the occurrences of the specified element from the specified int array.
5687 * <p>
5688 * All subsequent elements are shifted to the left (subtracts one from their indices).
5689 * If the array doesn't contain such an element, no elements are removed from the array.
5690 * {@code null} will be returned if the input array is {@code null}.
5691 * </p>
5692 *
5693 * @param array the input array, will not be modified, and may be {@code null}.
5694 * @param element the element to remove.
5695 * @return A new array containing the existing elements except the occurrences of the specified element.
5696 * @since 3.10
5697 */
5698 public static int[] removeAllOccurrences(final int[] array, final int element) {
5699 return (int[]) removeAt(array, indexesOf(array, element));
5700 }
5701
5702 /**
5703 * Removes the occurrences of the specified element from the specified long array.
5704 * <p>
5705 * All subsequent elements are shifted to the left (subtracts one from their indices).
5706 * If the array doesn't contain such an element, no elements are removed from the array.
5707 * {@code null} will be returned if the input array is {@code null}.
5708 * </p>
5709 *
5710 * @param array the input array, will not be modified, and may be {@code null}.
5711 * @param element the element to remove.
5712 * @return A new array containing the existing elements except the occurrences of the specified element.
5713 * @since 3.10
5714 */
5715 public static long[] removeAllOccurrences(final long[] array, final long element) {
5716 return (long[]) removeAt(array, indexesOf(array, element));
5717 }
5718
5719 /**
5720 * Removes the occurrences of the specified element from the specified short array.
5721 * <p>
5722 * All subsequent elements are shifted to the left (subtracts one from their indices).
5723 * If the array doesn't contain such an element, no elements are removed from the array.
5724 * {@code null} will be returned if the input array is {@code null}.
5725 * </p>
5726 *
5727 * @param array the input array, will not be modified, and may be {@code null}.
5728 * @param element the element to remove.
5729 * @return A new array containing the existing elements except the occurrences of the specified element.
5730 * @since 3.10
5731 */
5732 public static short[] removeAllOccurrences(final short[] array, final short element) {
5733 return (short[]) removeAt(array, indexesOf(array, element));
5734 }
5735
5736 /**
5737 * Removes the occurrences of the specified element from the specified array.
5738 * <p>
5739 * All subsequent elements are shifted to the left (subtracts one from their indices).
5740 * If the array doesn't contain such an element, no elements are removed from the array.
5741 * {@code null} will be returned if the input array is {@code null}.
5742 * </p>
5743 *
5744 * @param <T> the type of object in the array, may be {@code null}.
5745 * @param array the input array, will not be modified, and may be {@code null}.
5746 * @param element the element to remove, may be {@code null}.
5747 * @return A new array containing the existing elements except the occurrences of the specified element.
5748 * @since 3.10
5749 */
5750 public static <T> T[] removeAllOccurrences(final T[] array, final T element) {
5751 return (T[]) removeAt(array, indexesOf(array, element));
5752 }
5753
5754 /**
5755 * Removes multiple array elements specified by indices.
5756 *
5757 * @param array the input array, will not be modified, and may be {@code null}.
5758 * @param indices to remove.
5759 * @return new array of same type minus elements specified by the set bits in {@code indices}.
5760 */
5761 // package protected for access by unit tests
5762 static Object removeAt(final Object array, final BitSet indices) {
5763 if (array == null) {
5764 return null;
5765 }
5766 final int srcLength = getLength(array);
5767 // No need to check maxIndex here, because method only currently called from removeElements()
5768 // which guarantee to generate only valid bit entries.
5769 // final int maxIndex = indices.length();
5770 // if (maxIndex > srcLength) {
5771 // throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength);
5772 // }
5773 final int removals = indices.cardinality(); // true bits are items to remove
5774 final Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals);
5775 int srcIndex = 0;
5776 int destIndex = 0;
5777 int count;
5778 int set;
5779 while ((set = indices.nextSetBit(srcIndex)) != -1) {
5780 count = set - srcIndex;
5781 if (count > 0) {
5782 System.arraycopy(array, srcIndex, result, destIndex, count);
5783 destIndex += count;
5784 }
5785 srcIndex = indices.nextClearBit(set);
5786 }
5787 count = srcLength - srcIndex;
5788 if (count > 0) {
5789 System.arraycopy(array, srcIndex, result, destIndex, count);
5790 }
5791 return result;
5792 }
5793
5794 /**
5795 * Removes the first occurrence of the specified element from the
5796 * specified array. All subsequent elements are shifted to the left
5797 * (subtracts one from their indices). If the array doesn't contain
5798 * such an element, no elements are removed from the array.
5799 * <p>
5800 * This method returns a new array with the same elements of the input
5801 * array except the first occurrence of the specified element. The component
5802 * type of the returned array is always the same as that of the input
5803 * array.
5804 * </p>
5805 * <pre>
5806 * ArrayUtils.removeElement(null, true) = null
5807 * ArrayUtils.removeElement([], true) = []
5808 * ArrayUtils.removeElement([true], false) = [true]
5809 * ArrayUtils.removeElement([true, false], false) = [true]
5810 * ArrayUtils.removeElement([true, false, true], true) = [false, true]
5811 * </pre>
5812 *
5813 * @param array the input array, may be {@code null}.
5814 * @param element the element to be removed.
5815 * @return A new array containing the existing elements except the first
5816 * occurrence of the specified element.
5817 * @since 2.1
5818 */
5819 public static boolean[] removeElement(final boolean[] array, final boolean element) {
5820 final int index = indexOf(array, element);
5821 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
5822 }
5823
5824 /**
5825 * Removes the first occurrence of the specified element from the
5826 * specified array. All subsequent elements are shifted to the left
5827 * (subtracts one from their indices). If the array doesn't contain
5828 * such an element, no elements are removed from the array.
5829 * <p>
5830 * This method returns a new array with the same elements of the input
5831 * array except the first occurrence of the specified element. The component
5832 * type of the returned array is always the same as that of the input
5833 * array.
5834 * </p>
5835 * <pre>
5836 * ArrayUtils.removeElement(null, 1) = null
5837 * ArrayUtils.removeElement([], 1) = []
5838 * ArrayUtils.removeElement([1], 0) = [1]
5839 * ArrayUtils.removeElement([1, 0], 0) = [1]
5840 * ArrayUtils.removeElement([1, 0, 1], 1) = [0, 1]
5841 * </pre>
5842 *
5843 * @param array the input array, may be {@code null}.
5844 * @param element the element to be removed.
5845 * @return A new array containing the existing elements except the first
5846 * occurrence of the specified element.
5847 * @since 2.1
5848 */
5849 public static byte[] removeElement(final byte[] array, final byte element) {
5850 final int index = indexOf(array, element);
5851 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
5852 }
5853
5854 /**
5855 * Removes the first occurrence of the specified element from the
5856 * specified array. All subsequent elements are shifted to the left
5857 * (subtracts one from their indices). If the array doesn't contain
5858 * such an element, no elements are removed from the array.
5859 * <p>
5860 * This method returns a new array with the same elements of the input
5861 * array except the first occurrence of the specified element. The component
5862 * type of the returned array is always the same as that of the input
5863 * array.
5864 * </p>
5865 * <pre>
5866 * ArrayUtils.removeElement(null, 'a') = null
5867 * ArrayUtils.removeElement([], 'a') = []
5868 * ArrayUtils.removeElement(['a'], 'b') = ['a']
5869 * ArrayUtils.removeElement(['a', 'b'], 'a') = ['b']
5870 * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
5871 * </pre>
5872 *
5873 * @param array the input array, may be {@code null}.
5874 * @param element the element to be removed.
5875 * @return A new array containing the existing elements except the first
5876 * occurrence of the specified element.
5877 * @since 2.1
5878 */
5879 public static char[] removeElement(final char[] array, final char element) {
5880 final int index = indexOf(array, element);
5881 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
5882 }
5883
5884 /**
5885 * Removes the first occurrence of the specified element from the
5886 * specified array. All subsequent elements are shifted to the left
5887 * (subtracts one from their indices). If the array doesn't contain
5888 * such an element, no elements are removed from the array.
5889 * <p>
5890 * This method returns a new array with the same elements of the input
5891 * array except the first occurrence of the specified element. The component
5892 * type of the returned array is always the same as that of the input
5893 * array.
5894 * </p>
5895 * <pre>
5896 * ArrayUtils.removeElement(null, 1.1) = null
5897 * ArrayUtils.removeElement([], 1.1) = []
5898 * ArrayUtils.removeElement([1.1], 1.2) = [1.1]
5899 * ArrayUtils.removeElement([1.1, 2.3], 1.1) = [2.3]
5900 * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
5901 * </pre>
5902 *
5903 * @param array the input array, may be {@code null}.
5904 * @param element the element to be removed.
5905 * @return A new array containing the existing elements except the first
5906 * occurrence of the specified element.
5907 * @since 2.1
5908 */
5909 public static double[] removeElement(final double[] array, final double element) {
5910 final int index = indexOf(array, element);
5911 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
5912 }
5913
5914 /**
5915 * Removes the first occurrence of the specified element from the
5916 * specified array. All subsequent elements are shifted to the left
5917 * (subtracts one from their indices). If the array doesn't contain
5918 * such an element, no elements are removed from the array.
5919 * <p>
5920 * This method returns a new array with the same elements of the input
5921 * array except the first occurrence of the specified element. The component
5922 * type of the returned array is always the same as that of the input
5923 * array.
5924 * </p>
5925 * <pre>
5926 * ArrayUtils.removeElement(null, 1.1) = null
5927 * ArrayUtils.removeElement([], 1.1) = []
5928 * ArrayUtils.removeElement([1.1], 1.2) = [1.1]
5929 * ArrayUtils.removeElement([1.1, 2.3], 1.1) = [2.3]
5930 * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
5931 * </pre>
5932 *
5933 * @param array the input array, may be {@code null}.
5934 * @param element the element to be removed.
5935 * @return A new array containing the existing elements except the first
5936 * occurrence of the specified element.
5937 * @since 2.1
5938 */
5939 public static float[] removeElement(final float[] array, final float element) {
5940 final int index = indexOf(array, element);
5941 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
5942 }
5943
5944 /**
5945 * Removes the first occurrence of the specified element from the
5946 * specified array. All subsequent elements are shifted to the left
5947 * (subtracts one from their indices). If the array doesn't contain
5948 * such an element, no elements are removed from the array.
5949 * <p>
5950 * This method returns a new array with the same elements of the input
5951 * array except the first occurrence of the specified element. The component
5952 * type of the returned array is always the same as that of the input
5953 * array.
5954 * </p>
5955 * <pre>
5956 * ArrayUtils.removeElement(null, 1) = null
5957 * ArrayUtils.removeElement([], 1) = []
5958 * ArrayUtils.removeElement([1], 2) = [1]
5959 * ArrayUtils.removeElement([1, 3], 1) = [3]
5960 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
5961 * </pre>
5962 *
5963 * @param array the input array, may be {@code null}.
5964 * @param element the element to be removed.
5965 * @return A new array containing the existing elements except the first
5966 * occurrence of the specified element.
5967 * @since 2.1
5968 */
5969 public static int[] removeElement(final int[] array, final int element) {
5970 final int index = indexOf(array, element);
5971 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
5972 }
5973
5974 /**
5975 * Removes the first occurrence of the specified element from the
5976 * specified array. All subsequent elements are shifted to the left
5977 * (subtracts one from their indices). If the array doesn't contain
5978 * such an element, no elements are removed from the array.
5979 * <p>
5980 * This method returns a new array with the same elements of the input
5981 * array except the first occurrence of the specified element. The component
5982 * type of the returned array is always the same as that of the input
5983 * array.
5984 * </p>
5985 * <pre>
5986 * ArrayUtils.removeElement(null, 1) = null
5987 * ArrayUtils.removeElement([], 1) = []
5988 * ArrayUtils.removeElement([1], 2) = [1]
5989 * ArrayUtils.removeElement([1, 3], 1) = [3]
5990 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
5991 * </pre>
5992 *
5993 * @param array the input array, may be {@code null}.
5994 * @param element the element to be removed.
5995 * @return A new array containing the existing elements except the first
5996 * occurrence of the specified element.
5997 * @since 2.1
5998 */
5999 public static long[] removeElement(final long[] array, final long element) {
6000 final int index = indexOf(array, element);
6001 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6002 }
6003
6004 /**
6005 * Removes the first occurrence of the specified element from the
6006 * specified array. All subsequent elements are shifted to the left
6007 * (subtracts one from their indices). If the array doesn't contain
6008 * such an element, no elements are removed from the array.
6009 * <p>
6010 * This method returns a new array with the same elements of the input
6011 * array except the first occurrence of the specified element. The component
6012 * type of the returned array is always the same as that of the input
6013 * array.
6014 * </p>
6015 * <pre>
6016 * ArrayUtils.removeElement(null, 1) = null
6017 * ArrayUtils.removeElement([], 1) = []
6018 * ArrayUtils.removeElement([1], 2) = [1]
6019 * ArrayUtils.removeElement([1, 3], 1) = [3]
6020 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
6021 * </pre>
6022 *
6023 * @param array the input array, may be {@code null}.
6024 * @param element the element to be removed.
6025 * @return A new array containing the existing elements except the first
6026 * occurrence of the specified element.
6027 * @since 2.1
6028 */
6029 public static short[] removeElement(final short[] array, final short element) {
6030 final int index = indexOf(array, element);
6031 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6032 }
6033
6034 /**
6035 * Removes the first occurrence of the specified element from the
6036 * specified array. All subsequent elements are shifted to the left
6037 * (subtracts one from their indices). If the array doesn't contain
6038 * such an element, no elements are removed from the array.
6039 * <p>
6040 * This method returns a new array with the same elements of the input
6041 * array except the first occurrence of the specified element. The component
6042 * type of the returned array is always the same as that of the input
6043 * array.
6044 * </p>
6045 * <pre>
6046 * ArrayUtils.removeElement(null, "a") = null
6047 * ArrayUtils.removeElement([], "a") = []
6048 * ArrayUtils.removeElement(["a"], "b") = ["a"]
6049 * ArrayUtils.removeElement(["a", "b"], "a") = ["b"]
6050 * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
6051 * </pre>
6052 *
6053 * @param <T> the component type of the array
6054 * @param array the input array, may be {@code null}.
6055 * @param element the element to be removed, may be {@code null}.
6056 * @return A new array containing the existing elements except the first
6057 * occurrence of the specified element.
6058 * @since 2.1
6059 */
6060 public static <T> T[] removeElement(final T[] array, final Object element) {
6061 final int index = indexOf(array, element);
6062 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6063 }
6064
6065 /**
6066 * Removes occurrences of specified elements, in specified quantities,
6067 * from the specified array. All subsequent elements are shifted left.
6068 * For any element-to-be-removed specified in greater quantities than
6069 * contained in the original array, no change occurs beyond the
6070 * removal of the existing matching items.
6071 * <p>
6072 * This method returns a new array with the same elements of the input
6073 * array except for the earliest-encountered occurrences of the specified
6074 * elements. The component type of the returned array is always the same
6075 * as that of the input array.
6076 * </p>
6077 * <pre>
6078 * ArrayUtils.removeElements(null, true, false) = null
6079 * ArrayUtils.removeElements([], true, false) = []
6080 * ArrayUtils.removeElements([true], false, false) = [true]
6081 * ArrayUtils.removeElements([true, false], true, true) = [false]
6082 * ArrayUtils.removeElements([true, false, true], true) = [false, true]
6083 * ArrayUtils.removeElements([true, false, true], true, true) = [false]
6084 * </pre>
6085 *
6086 * @param array the input array, will not be modified, and may be {@code null}.
6087 * @param values the values to be removed.
6088 * @return A new array containing the existing elements except the
6089 * earliest-encountered occurrences of the specified elements.
6090 * @since 3.0.1
6091 */
6092 public static boolean[] removeElements(final boolean[] array, final boolean... values) {
6093 if (isEmpty(array) || isEmpty(values)) {
6094 return clone(array);
6095 }
6096 final HashMap<Boolean, MutableInt> occurrences = new HashMap<>(2); // only two possible values here
6097 for (final boolean v : values) {
6098 increment(occurrences, Boolean.valueOf(v));
6099 }
6100 final BitSet toRemove = new BitSet();
6101 for (int i = 0; i < array.length; i++) {
6102 final boolean key = array[i];
6103 final MutableInt count = occurrences.get(key);
6104 if (count != null) {
6105 if (count.decrementAndGet() == 0) {
6106 occurrences.remove(key);
6107 }
6108 toRemove.set(i);
6109 }
6110 }
6111 return (boolean[]) removeAt(array, toRemove);
6112 }
6113
6114 /**
6115 * Removes occurrences of specified elements, in specified quantities,
6116 * from the specified array. All subsequent elements are shifted left.
6117 * For any element-to-be-removed specified in greater quantities than
6118 * contained in the original array, no change occurs beyond the
6119 * removal of the existing matching items.
6120 * <p>
6121 * This method returns a new array with the same elements of the input
6122 * array except for the earliest-encountered occurrences of the specified
6123 * elements. The component type of the returned array is always the same
6124 * as that of the input array.
6125 * </p>
6126 * <pre>
6127 * ArrayUtils.removeElements(null, 1, 2) = null
6128 * ArrayUtils.removeElements([], 1, 2) = []
6129 * ArrayUtils.removeElements([1], 2, 3) = [1]
6130 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6131 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6132 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6133 * </pre>
6134 *
6135 * @param array the input array, will not be modified, and may be {@code null}.
6136 * @param values the values to be removed.
6137 * @return A new array containing the existing elements except the
6138 * earliest-encountered occurrences of the specified elements.
6139 * @since 3.0.1
6140 */
6141 public static byte[] removeElements(final byte[] array, final byte... values) {
6142 if (isEmpty(array) || isEmpty(values)) {
6143 return clone(array);
6144 }
6145 final HashMap<Byte, MutableInt> occurrences = new HashMap<>(values.length);
6146 for (final byte v : values) {
6147 increment(occurrences, Byte.valueOf(v));
6148 }
6149 final BitSet toRemove = new BitSet();
6150 for (int i = 0; i < array.length; i++) {
6151 final byte key = array[i];
6152 final MutableInt count = occurrences.get(key);
6153 if (count != null) {
6154 if (count.decrementAndGet() == 0) {
6155 occurrences.remove(key);
6156 }
6157 toRemove.set(i);
6158 }
6159 }
6160 return (byte[]) removeAt(array, toRemove);
6161 }
6162
6163 /**
6164 * Removes occurrences of specified elements, in specified quantities,
6165 * from the specified array. All subsequent elements are shifted left.
6166 * For any element-to-be-removed specified in greater quantities than
6167 * contained in the original array, no change occurs beyond the
6168 * removal of the existing matching items.
6169 * <p>
6170 * This method returns a new array with the same elements of the input
6171 * array except for the earliest-encountered occurrences of the specified
6172 * elements. The component type of the returned array is always the same
6173 * as that of the input array.
6174 * </p>
6175 * <pre>
6176 * ArrayUtils.removeElements(null, 1, 2) = null
6177 * ArrayUtils.removeElements([], 1, 2) = []
6178 * ArrayUtils.removeElements([1], 2, 3) = [1]
6179 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6180 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6181 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6182 * </pre>
6183 *
6184 * @param array the input array, will not be modified, and may be {@code null}.
6185 * @param values the values to be removed.
6186 * @return A new array containing the existing elements except the
6187 * earliest-encountered occurrences of the specified elements.
6188 * @since 3.0.1
6189 */
6190 public static char[] removeElements(final char[] array, final char... values) {
6191 if (isEmpty(array) || isEmpty(values)) {
6192 return clone(array);
6193 }
6194 final HashMap<Character, MutableInt> occurrences = new HashMap<>(values.length);
6195 for (final char v : values) {
6196 increment(occurrences, Character.valueOf(v));
6197 }
6198 final BitSet toRemove = new BitSet();
6199 for (int i = 0; i < array.length; i++) {
6200 final char key = array[i];
6201 final MutableInt count = occurrences.get(key);
6202 if (count != null) {
6203 if (count.decrementAndGet() == 0) {
6204 occurrences.remove(key);
6205 }
6206 toRemove.set(i);
6207 }
6208 }
6209 return (char[]) removeAt(array, toRemove);
6210 }
6211
6212 /**
6213 * Removes occurrences of specified elements, in specified quantities,
6214 * from the specified array. All subsequent elements are shifted left.
6215 * For any element-to-be-removed specified in greater quantities than
6216 * contained in the original array, no change occurs beyond the
6217 * removal of the existing matching items.
6218 * <p>
6219 * This method returns a new array with the same elements of the input
6220 * array except for the earliest-encountered occurrences of the specified
6221 * elements. The component type of the returned array is always the same
6222 * as that of the input array.
6223 * </p>
6224 * <pre>
6225 * ArrayUtils.removeElements(null, 1, 2) = null
6226 * ArrayUtils.removeElements([], 1, 2) = []
6227 * ArrayUtils.removeElements([1], 2, 3) = [1]
6228 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6229 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6230 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6231 * </pre>
6232 *
6233 * @param array the input array, will not be modified, and may be {@code null}.
6234 * @param values the values to be removed.
6235 * @return A new array containing the existing elements except the
6236 * earliest-encountered occurrences of the specified elements.
6237 * @since 3.0.1
6238 */
6239 public static double[] removeElements(final double[] array, final double... values) {
6240 if (isEmpty(array) || isEmpty(values)) {
6241 return clone(array);
6242 }
6243 final HashMap<Double, MutableInt> occurrences = new HashMap<>(values.length);
6244 for (final double v : values) {
6245 increment(occurrences, Double.valueOf(v));
6246 }
6247 final BitSet toRemove = new BitSet();
6248 for (int i = 0; i < array.length; i++) {
6249 final double key = array[i];
6250 final MutableInt count = occurrences.get(key);
6251 if (count != null) {
6252 if (count.decrementAndGet() == 0) {
6253 occurrences.remove(key);
6254 }
6255 toRemove.set(i);
6256 }
6257 }
6258 return (double[]) removeAt(array, toRemove);
6259 }
6260
6261 /**
6262 * Removes occurrences of specified elements, in specified quantities,
6263 * from the specified array. All subsequent elements are shifted left.
6264 * For any element-to-be-removed specified in greater quantities than
6265 * contained in the original array, no change occurs beyond the
6266 * removal of the existing matching items.
6267 * <p>
6268 * This method returns a new array with the same elements of the input
6269 * array except for the earliest-encountered occurrences of the specified
6270 * elements. The component type of the returned array is always the same
6271 * as that of the input array.
6272 * </p>
6273 * <pre>
6274 * ArrayUtils.removeElements(null, 1, 2) = null
6275 * ArrayUtils.removeElements([], 1, 2) = []
6276 * ArrayUtils.removeElements([1], 2, 3) = [1]
6277 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6278 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6279 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6280 * </pre>
6281 *
6282 * @param array the input array, will not be modified, and may be {@code null}.
6283 * @param values the values to be removed.
6284 * @return A new array containing the existing elements except the
6285 * earliest-encountered occurrences of the specified elements.
6286 * @since 3.0.1
6287 */
6288 public static float[] removeElements(final float[] array, final float... values) {
6289 if (isEmpty(array) || isEmpty(values)) {
6290 return clone(array);
6291 }
6292 final HashMap<Float, MutableInt> occurrences = new HashMap<>(values.length);
6293 for (final float v : values) {
6294 increment(occurrences, Float.valueOf(v));
6295 }
6296 final BitSet toRemove = new BitSet();
6297 for (int i = 0; i < array.length; i++) {
6298 final float key = array[i];
6299 final MutableInt count = occurrences.get(key);
6300 if (count != null) {
6301 if (count.decrementAndGet() == 0) {
6302 occurrences.remove(key);
6303 }
6304 toRemove.set(i);
6305 }
6306 }
6307 return (float[]) removeAt(array, toRemove);
6308 }
6309
6310 /**
6311 * Removes occurrences of specified elements, in specified quantities,
6312 * from the specified array. All subsequent elements are shifted left.
6313 * For any element-to-be-removed specified in greater quantities than
6314 * contained in the original array, no change occurs beyond the
6315 * removal of the existing matching items.
6316 * <p>
6317 * This method returns a new array with the same elements of the input
6318 * array except for the earliest-encountered occurrences of the specified
6319 * elements. The component type of the returned array is always the same
6320 * as that of the input array.
6321 * </p>
6322 * <pre>
6323 * ArrayUtils.removeElements(null, 1, 2) = null
6324 * ArrayUtils.removeElements([], 1, 2) = []
6325 * ArrayUtils.removeElements([1], 2, 3) = [1]
6326 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6327 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6328 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6329 * </pre>
6330 *
6331 * @param array the input array, will not be modified, and may be {@code null}.
6332 * @param values the values to be removed.
6333 * @return A new array containing the existing elements except the
6334 * earliest-encountered occurrences of the specified elements.
6335 * @since 3.0.1
6336 */
6337 public static int[] removeElements(final int[] array, final int... values) {
6338 if (isEmpty(array) || isEmpty(values)) {
6339 return clone(array);
6340 }
6341 final HashMap<Integer, MutableInt> occurrences = new HashMap<>(values.length);
6342 for (final int v : values) {
6343 increment(occurrences, Integer.valueOf(v));
6344 }
6345 final BitSet toRemove = new BitSet();
6346 for (int i = 0; i < array.length; i++) {
6347 final int key = array[i];
6348 final MutableInt count = occurrences.get(key);
6349 if (count != null) {
6350 if (count.decrementAndGet() == 0) {
6351 occurrences.remove(key);
6352 }
6353 toRemove.set(i);
6354 }
6355 }
6356 return (int[]) removeAt(array, toRemove);
6357 }
6358
6359 /**
6360 * Removes occurrences of specified elements, in specified quantities,
6361 * from the specified array. All subsequent elements are shifted left.
6362 * For any element-to-be-removed specified in greater quantities than
6363 * contained in the original array, no change occurs beyond the
6364 * removal of the existing matching items.
6365 * <p>
6366 * This method returns a new array with the same elements of the input
6367 * array except for the earliest-encountered occurrences of the specified
6368 * elements. The component type of the returned array is always the same
6369 * as that of the input array.
6370 * </p>
6371 * <pre>
6372 * ArrayUtils.removeElements(null, 1, 2) = null
6373 * ArrayUtils.removeElements([], 1, 2) = []
6374 * ArrayUtils.removeElements([1], 2, 3) = [1]
6375 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6376 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6377 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6378 * </pre>
6379 *
6380 * @param array the input array, will not be modified, and may be {@code null}.
6381 * @param values the values to be removed.
6382 * @return A new array containing the existing elements except the
6383 * earliest-encountered occurrences of the specified elements.
6384 * @since 3.0.1
6385 */
6386 public static long[] removeElements(final long[] array, final long... values) {
6387 if (isEmpty(array) || isEmpty(values)) {
6388 return clone(array);
6389 }
6390 final HashMap<Long, MutableInt> occurrences = new HashMap<>(values.length);
6391 for (final long v : values) {
6392 increment(occurrences, Long.valueOf(v));
6393 }
6394 final BitSet toRemove = new BitSet();
6395 for (int i = 0; i < array.length; i++) {
6396 final long key = array[i];
6397 final MutableInt count = occurrences.get(key);
6398 if (count != null) {
6399 if (count.decrementAndGet() == 0) {
6400 occurrences.remove(key);
6401 }
6402 toRemove.set(i);
6403 }
6404 }
6405 return (long[]) removeAt(array, toRemove);
6406 }
6407
6408 /**
6409 * Removes occurrences of specified elements, in specified quantities,
6410 * from the specified array. All subsequent elements are shifted left.
6411 * For any element-to-be-removed specified in greater quantities than
6412 * contained in the original array, no change occurs beyond the
6413 * removal of the existing matching items.
6414 * <p>
6415 * This method returns a new array with the same elements of the input
6416 * array except for the earliest-encountered occurrences of the specified
6417 * elements. The component type of the returned array is always the same
6418 * as that of the input array.
6419 * </p>
6420 * <pre>
6421 * ArrayUtils.removeElements(null, 1, 2) = null
6422 * ArrayUtils.removeElements([], 1, 2) = []
6423 * ArrayUtils.removeElements([1], 2, 3) = [1]
6424 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6425 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6426 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6427 * </pre>
6428 *
6429 * @param array the input array, will not be modified, and may be {@code null}.
6430 * @param values the values to be removed.
6431 * @return A new array containing the existing elements except the
6432 * earliest-encountered occurrences of the specified elements.
6433 * @since 3.0.1
6434 */
6435 public static short[] removeElements(final short[] array, final short... values) {
6436 if (isEmpty(array) || isEmpty(values)) {
6437 return clone(array);
6438 }
6439 final HashMap<Short, MutableInt> occurrences = new HashMap<>(values.length);
6440 for (final short v : values) {
6441 increment(occurrences, Short.valueOf(v));
6442 }
6443 final BitSet toRemove = new BitSet();
6444 for (int i = 0; i < array.length; i++) {
6445 final short key = array[i];
6446 final MutableInt count = occurrences.get(key);
6447 if (count != null) {
6448 if (count.decrementAndGet() == 0) {
6449 occurrences.remove(key);
6450 }
6451 toRemove.set(i);
6452 }
6453 }
6454 return (short[]) removeAt(array, toRemove);
6455 }
6456
6457 /**
6458 * Removes occurrences of specified elements, in specified quantities,
6459 * from the specified array. All subsequent elements are shifted left.
6460 * For any element-to-be-removed specified in greater quantities than
6461 * contained in the original array, no change occurs beyond the
6462 * removal of the existing matching items.
6463 * <p>
6464 * This method returns a new array with the same elements of the input
6465 * array except for the earliest-encountered occurrences of the specified
6466 * elements. The component type of the returned array is always the same
6467 * as that of the input array.
6468 * </p>
6469 * <pre>
6470 * ArrayUtils.removeElements(null, "a", "b") = null
6471 * ArrayUtils.removeElements([], "a", "b") = []
6472 * ArrayUtils.removeElements(["a"], "b", "c") = ["a"]
6473 * ArrayUtils.removeElements(["a", "b"], "a", "c") = ["b"]
6474 * ArrayUtils.removeElements(["a", "b", "a"], "a") = ["b", "a"]
6475 * ArrayUtils.removeElements(["a", "b", "a"], "a", "a") = ["b"]
6476 * </pre>
6477 *
6478 * @param <T> the component type of the array
6479 * @param array the input array, will not be modified, and may be {@code null}.
6480 * @param values the values to be removed.
6481 * @return A new array containing the existing elements except the
6482 * earliest-encountered occurrences of the specified elements.
6483 * @since 3.0.1
6484 */
6485 @SafeVarargs
6486 public static <T> T[] removeElements(final T[] array, final T... values) {
6487 if (isEmpty(array) || isEmpty(values)) {
6488 return clone(array);
6489 }
6490 final HashMap<T, MutableInt> occurrences = new HashMap<>(values.length);
6491 for (final T v : values) {
6492 increment(occurrences, v);
6493 }
6494 final BitSet toRemove = new BitSet();
6495 for (int i = 0; i < array.length; i++) {
6496 final T key = array[i];
6497 final MutableInt count = occurrences.get(key);
6498 if (count != null) {
6499 if (count.decrementAndGet() == 0) {
6500 occurrences.remove(key);
6501 }
6502 toRemove.set(i);
6503 }
6504 }
6505 @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
6506 final T[] result = (T[]) removeAt(array, toRemove);
6507 return result;
6508 }
6509
6510 /**
6511 * Reverses the order of the given array.
6512 * <p>
6513 * This method does nothing for a {@code null} input array.
6514 * </p>
6515 *
6516 * @param array the array to reverse, may be {@code null}.
6517 */
6518 public static void reverse(final boolean[] array) {
6519 if (array == null) {
6520 return;
6521 }
6522 reverse(array, 0, array.length);
6523 }
6524
6525 /**
6526 * Reverses the order of the given array in the given range.
6527 * <p>
6528 * This method does nothing for a {@code null} input array.
6529 * </p>
6530 *
6531 * @param array
6532 * the array to reverse, may be {@code null}.
6533 * @param startIndexInclusive
6534 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6535 * change.
6536 * @param endIndexExclusive
6537 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6538 * change. Overvalue (>array.length) is demoted to array length.
6539 * @since 3.2
6540 */
6541 public static void reverse(final boolean[] array, final int startIndexInclusive, final int endIndexExclusive) {
6542 if (array == null) {
6543 return;
6544 }
6545 int i = Math.max(startIndexInclusive, 0);
6546 int j = Math.min(array.length, endIndexExclusive) - 1;
6547 boolean tmp;
6548 while (j > i) {
6549 tmp = array[j];
6550 array[j] = array[i];
6551 array[i] = tmp;
6552 j--;
6553 i++;
6554 }
6555 }
6556
6557 /**
6558 * Reverses the order of the given array.
6559 * <p>
6560 * This method does nothing for a {@code null} input array.
6561 * </p>
6562 *
6563 * @param array the array to reverse, may be {@code null}
6564 */
6565 public static void reverse(final byte[] array) {
6566 if (array != null) {
6567 reverse(array, 0, array.length);
6568 }
6569 }
6570
6571 /**
6572 * Reverses the order of the given array in the given range.
6573 * <p>
6574 * This method does nothing for a {@code null} input array.
6575 * </p>
6576 *
6577 * @param array
6578 * the array to reverse, may be {@code null}
6579 * @param startIndexInclusive
6580 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6581 * change.
6582 * @param endIndexExclusive
6583 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6584 * change. Overvalue (>array.length) is demoted to array length.
6585 * @since 3.2
6586 */
6587 public static void reverse(final byte[] array, final int startIndexInclusive, final int endIndexExclusive) {
6588 if (array == null) {
6589 return;
6590 }
6591 int i = Math.max(startIndexInclusive, 0);
6592 int j = Math.min(array.length, endIndexExclusive) - 1;
6593 byte tmp;
6594 while (j > i) {
6595 tmp = array[j];
6596 array[j] = array[i];
6597 array[i] = tmp;
6598 j--;
6599 i++;
6600 }
6601 }
6602
6603 /**
6604 * Reverses the order of the given array.
6605 * <p>
6606 * This method does nothing for a {@code null} input array.
6607 * </p>
6608 *
6609 * @param array the array to reverse, may be {@code null}
6610 */
6611 public static void reverse(final char[] array) {
6612 if (array != null) {
6613 reverse(array, 0, array.length);
6614 }
6615 }
6616
6617 /**
6618 * Reverses the order of the given array in the given range.
6619 * <p>
6620 * This method does nothing for a {@code null} input array.
6621 * </p>
6622 *
6623 * @param array
6624 * the array to reverse, may be {@code null}
6625 * @param startIndexInclusive
6626 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6627 * change.
6628 * @param endIndexExclusive
6629 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6630 * change. Overvalue (>array.length) is demoted to array length.
6631 * @since 3.2
6632 */
6633 public static void reverse(final char[] array, final int startIndexInclusive, final int endIndexExclusive) {
6634 if (array == null) {
6635 return;
6636 }
6637 int i = Math.max(startIndexInclusive, 0);
6638 int j = Math.min(array.length, endIndexExclusive) - 1;
6639 char tmp;
6640 while (j > i) {
6641 tmp = array[j];
6642 array[j] = array[i];
6643 array[i] = tmp;
6644 j--;
6645 i++;
6646 }
6647 }
6648
6649 /**
6650 * Reverses the order of the given array.
6651 * <p>
6652 * This method does nothing for a {@code null} input array.
6653 * </p>
6654 *
6655 * @param array the array to reverse, may be {@code null}
6656 */
6657 public static void reverse(final double[] array) {
6658 if (array != null) {
6659 reverse(array, 0, array.length);
6660 }
6661 }
6662
6663 /**
6664 * Reverses the order of the given array in the given range.
6665 * <p>
6666 * This method does nothing for a {@code null} input array.
6667 * </p>
6668 *
6669 * @param array
6670 * the array to reverse, may be {@code null}
6671 * @param startIndexInclusive
6672 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6673 * change.
6674 * @param endIndexExclusive
6675 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6676 * change. Overvalue (>array.length) is demoted to array length.
6677 * @since 3.2
6678 */
6679 public static void reverse(final double[] array, final int startIndexInclusive, final int endIndexExclusive) {
6680 if (array == null) {
6681 return;
6682 }
6683 int i = Math.max(startIndexInclusive, 0);
6684 int j = Math.min(array.length, endIndexExclusive) - 1;
6685 double tmp;
6686 while (j > i) {
6687 tmp = array[j];
6688 array[j] = array[i];
6689 array[i] = tmp;
6690 j--;
6691 i++;
6692 }
6693 }
6694
6695 /**
6696 * Reverses the order of the given array.
6697 * <p>
6698 * This method does nothing for a {@code null} input array.
6699 * </p>
6700 *
6701 * @param array the array to reverse, may be {@code null}.
6702 */
6703 public static void reverse(final float[] array) {
6704 if (array != null) {
6705 reverse(array, 0, array.length);
6706 }
6707 }
6708
6709 /**
6710 * Reverses the order of the given array in the given range.
6711 * <p>
6712 * This method does nothing for a {@code null} input array.
6713 * </p>
6714 *
6715 * @param array
6716 * the array to reverse, may be {@code null}.
6717 * @param startIndexInclusive
6718 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6719 * change.
6720 * @param endIndexExclusive
6721 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6722 * change. Overvalue (>array.length) is demoted to array length.
6723 * @since 3.2
6724 */
6725 public static void reverse(final float[] array, final int startIndexInclusive, final int endIndexExclusive) {
6726 if (array == null) {
6727 return;
6728 }
6729 int i = Math.max(startIndexInclusive, 0);
6730 int j = Math.min(array.length, endIndexExclusive) - 1;
6731 float tmp;
6732 while (j > i) {
6733 tmp = array[j];
6734 array[j] = array[i];
6735 array[i] = tmp;
6736 j--;
6737 i++;
6738 }
6739 }
6740
6741 /**
6742 * Reverses the order of the given array.
6743 * <p>
6744 * This method does nothing for a {@code null} input array.
6745 * </p>
6746 *
6747 * @param array the array to reverse, may be {@code null}.
6748 */
6749 public static void reverse(final int[] array) {
6750 if (array != null) {
6751 reverse(array, 0, array.length);
6752 }
6753 }
6754
6755 /**
6756 * Reverses the order of the given array in the given range.
6757 * <p>
6758 * This method does nothing for a {@code null} input array.
6759 * </p>
6760 *
6761 * @param array
6762 * the array to reverse, may be {@code null}.
6763 * @param startIndexInclusive
6764 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6765 * change.
6766 * @param endIndexExclusive
6767 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6768 * change. Overvalue (>array.length) is demoted to array length.
6769 * @since 3.2
6770 */
6771 public static void reverse(final int[] array, final int startIndexInclusive, final int endIndexExclusive) {
6772 if (array == null) {
6773 return;
6774 }
6775 int i = Math.max(startIndexInclusive, 0);
6776 int j = Math.min(array.length, endIndexExclusive) - 1;
6777 int tmp;
6778 while (j > i) {
6779 tmp = array[j];
6780 array[j] = array[i];
6781 array[i] = tmp;
6782 j--;
6783 i++;
6784 }
6785 }
6786
6787 /**
6788 * Reverses the order of the given array.
6789 * <p>
6790 * This method does nothing for a {@code null} input array.
6791 * </p>
6792 *
6793 * @param array the array to reverse, may be {@code null}.
6794 */
6795 public static void reverse(final long[] array) {
6796 if (array != null) {
6797 reverse(array, 0, array.length);
6798 }
6799 }
6800
6801 /**
6802 * Reverses the order of the given array in the given range.
6803 * <p>
6804 * This method does nothing for a {@code null} input array.
6805 * </p>
6806 *
6807 * @param array
6808 * the array to reverse, may be {@code null}.
6809 * @param startIndexInclusive
6810 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6811 * change.
6812 * @param endIndexExclusive
6813 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6814 * change. Overvalue (>array.length) is demoted to array length.
6815 * @since 3.2
6816 */
6817 public static void reverse(final long[] array, final int startIndexInclusive, final int endIndexExclusive) {
6818 if (array == null) {
6819 return;
6820 }
6821 int i = Math.max(startIndexInclusive, 0);
6822 int j = Math.min(array.length, endIndexExclusive) - 1;
6823 long tmp;
6824 while (j > i) {
6825 tmp = array[j];
6826 array[j] = array[i];
6827 array[i] = tmp;
6828 j--;
6829 i++;
6830 }
6831 }
6832
6833 /**
6834 * Reverses the order of the given array.
6835 * <p>
6836 * There is no special handling for multi-dimensional arrays.
6837 * </p>
6838 * <p>
6839 * This method does nothing for a {@code null} input array.
6840 * </p>
6841 *
6842 * @param array the array to reverse, may be {@code null}.
6843 */
6844 public static void reverse(final Object[] array) {
6845 if (array != null) {
6846 reverse(array, 0, array.length);
6847 }
6848 }
6849
6850 /**
6851 * Reverses the order of the given array in the given range.
6852 * <p>
6853 * This method does nothing for a {@code null} input array.
6854 * </p>
6855 *
6856 * @param array
6857 * the array to reverse, may be {@code null}.
6858 * @param startIndexInclusive
6859 * the starting index. Under value (<0) is promoted to 0, over value (>array.length) results in no
6860 * change.
6861 * @param endIndexExclusive
6862 * elements up to endIndex-1 are reversed in the array. Under value (< start index) results in no
6863 * change. Over value (>array.length) is demoted to array length.
6864 * @since 3.2
6865 */
6866 public static void reverse(final Object[] array, final int startIndexInclusive, final int endIndexExclusive) {
6867 if (array == null) {
6868 return;
6869 }
6870 int i = Math.max(startIndexInclusive, 0);
6871 int j = Math.min(array.length, endIndexExclusive) - 1;
6872 Object tmp;
6873 while (j > i) {
6874 tmp = array[j];
6875 array[j] = array[i];
6876 array[i] = tmp;
6877 j--;
6878 i++;
6879 }
6880 }
6881
6882 /**
6883 * Reverses the order of the given array.
6884 * <p>
6885 * This method does nothing for a {@code null} input array.
6886 * </p>
6887 *
6888 * @param array the array to reverse, may be {@code null}.
6889 */
6890 public static void reverse(final short[] array) {
6891 if (array != null) {
6892 reverse(array, 0, array.length);
6893 }
6894 }
6895
6896 /**
6897 * Reverses the order of the given array in the given range.
6898 * <p>
6899 * This method does nothing for a {@code null} input array.
6900 * </p>
6901 *
6902 * @param array
6903 * the array to reverse, may be {@code null}.
6904 * @param startIndexInclusive
6905 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6906 * change.
6907 * @param endIndexExclusive
6908 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6909 * change. Overvalue (>array.length) is demoted to array length.
6910 * @since 3.2
6911 */
6912 public static void reverse(final short[] array, final int startIndexInclusive, final int endIndexExclusive) {
6913 if (array == null) {
6914 return;
6915 }
6916 int i = Math.max(startIndexInclusive, 0);
6917 int j = Math.min(array.length, endIndexExclusive) - 1;
6918 short tmp;
6919 while (j > i) {
6920 tmp = array[j];
6921 array[j] = array[i];
6922 array[i] = tmp;
6923 j--;
6924 i++;
6925 }
6926 }
6927
6928 /**
6929 * Sets all elements of the specified array, using the provided generator supplier to compute each element.
6930 * <p>
6931 * If the generator supplier throws an exception, it is relayed to the caller and the array is left in an indeterminate
6932 * state.
6933 * </p>
6934 *
6935 * @param <T> type of elements of the array, may be {@code null}.
6936 * @param array array to be initialized, may be {@code null}.
6937 * @param generator a function accepting an index and producing the desired value for that position.
6938 * @return the input array
6939 * @since 3.13.0
6940 */
6941 public static <T> T[] setAll(final T[] array, final IntFunction<? extends T> generator) {
6942 if (array != null && generator != null) {
6943 Arrays.setAll(array, generator);
6944 }
6945 return array;
6946 }
6947
6948 /**
6949 * Sets all elements of the specified array, using the provided generator supplier to compute each element.
6950 * <p>
6951 * If the generator supplier throws an exception, it is relayed to the caller and the array is left in an indeterminate
6952 * state.
6953 * </p>
6954 *
6955 * @param <T> type of elements of the array, may be {@code null}.
6956 * @param array array to be initialized, may be {@code null}.
6957 * @param generator a function accepting an index and producing the desired value for that position.
6958 * @return the input array
6959 * @since 3.13.0
6960 */
6961 public static <T> T[] setAll(final T[] array, final Supplier<? extends T> generator) {
6962 if (array != null && generator != null) {
6963 for (int i = 0; i < array.length; i++) {
6964 array[i] = generator.get();
6965 }
6966 }
6967 return array;
6968 }
6969
6970 /**
6971 * Shifts the order of the given boolean array.
6972 *
6973 * <p>There is no special handling for multi-dimensional arrays. This method
6974 * does nothing for {@code null} or empty input arrays.</p>
6975 *
6976 * @param array the array to shift, may be {@code null}.
6977 * @param offset
6978 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
6979 * rotate, than the effective offset is modulo the number of elements to rotate.
6980 * @since 3.5
6981 */
6982 public static void shift(final boolean[] array, final int offset) {
6983 if (array != null) {
6984 shift(array, 0, array.length, offset);
6985 }
6986 }
6987
6988 /**
6989 * Shifts the order of a series of elements in the given boolean array.
6990 *
6991 * <p>There is no special handling for multi-dimensional arrays. This method
6992 * does nothing for {@code null} or empty input arrays.</p>
6993 *
6994 * @param array
6995 * the array to shift, may be {@code null}.
6996 * @param startIndexInclusive
6997 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6998 * change.
6999 * @param endIndexExclusive
7000 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7001 * change. Overvalue (>array.length) is demoted to array length.
7002 * @param offset
7003 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7004 * rotate, than the effective offset is modulo the number of elements to rotate.
7005 * @since 3.5
7006 */
7007 public static void shift(final boolean[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7008 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7009 return;
7010 }
7011 startIndexInclusive = max0(startIndexInclusive);
7012 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7013 int n = endIndexExclusive - startIndexInclusive;
7014 if (n <= 1) {
7015 return;
7016 }
7017 offset %= n;
7018 if (offset < 0) {
7019 offset += n;
7020 }
7021 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7022 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7023 while (n > 1 && offset > 0) {
7024 final int nOffset = n - offset;
7025 if (offset > nOffset) {
7026 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7027 n = offset;
7028 offset -= nOffset;
7029 } else if (offset < nOffset) {
7030 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7031 startIndexInclusive += offset;
7032 n = nOffset;
7033 } else {
7034 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7035 break;
7036 }
7037 }
7038 }
7039
7040 /**
7041 * Shifts the order of the given byte array.
7042 *
7043 * <p>There is no special handling for multi-dimensional arrays. This method
7044 * does nothing for {@code null} or empty input arrays.</p>
7045 *
7046 * @param array the array to shift, may be {@code null}.
7047 * @param offset
7048 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7049 * rotate, than the effective offset is modulo the number of elements to rotate.
7050 * @since 3.5
7051 */
7052 public static void shift(final byte[] array, final int offset) {
7053 if (array != null) {
7054 shift(array, 0, array.length, offset);
7055 }
7056 }
7057
7058 /**
7059 * Shifts the order of a series of elements in the given byte array.
7060 *
7061 * <p>There is no special handling for multi-dimensional arrays. This method
7062 * does nothing for {@code null} or empty input arrays.</p>
7063 *
7064 * @param array
7065 * the array to shift, may be {@code null}.
7066 * @param startIndexInclusive
7067 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7068 * change.
7069 * @param endIndexExclusive
7070 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7071 * change. Overvalue (>array.length) is demoted to array length.
7072 * @param offset
7073 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7074 * rotate, than the effective offset is modulo the number of elements to rotate.
7075 * @since 3.5
7076 */
7077 public static void shift(final byte[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7078 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7079 return;
7080 }
7081 startIndexInclusive = max0(startIndexInclusive);
7082 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7083 int n = endIndexExclusive - startIndexInclusive;
7084 if (n <= 1) {
7085 return;
7086 }
7087 offset %= n;
7088 if (offset < 0) {
7089 offset += n;
7090 }
7091 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7092 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7093 while (n > 1 && offset > 0) {
7094 final int nOffset = n - offset;
7095 if (offset > nOffset) {
7096 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7097 n = offset;
7098 offset -= nOffset;
7099 } else if (offset < nOffset) {
7100 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7101 startIndexInclusive += offset;
7102 n = nOffset;
7103 } else {
7104 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7105 break;
7106 }
7107 }
7108 }
7109
7110 /**
7111 * Shifts the order of the given char array.
7112 *
7113 * <p>There is no special handling for multi-dimensional arrays. This method
7114 * does nothing for {@code null} or empty input arrays.</p>
7115 *
7116 * @param array the array to shift, may be {@code null}.
7117 * @param offset
7118 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7119 * rotate, than the effective offset is modulo the number of elements to rotate.
7120 * @since 3.5
7121 */
7122 public static void shift(final char[] array, final int offset) {
7123 if (array != null) {
7124 shift(array, 0, array.length, offset);
7125 }
7126 }
7127
7128 /**
7129 * Shifts the order of a series of elements in the given char array.
7130 *
7131 * <p>There is no special handling for multi-dimensional arrays. This method
7132 * does nothing for {@code null} or empty input arrays.</p>
7133 *
7134 * @param array
7135 * the array to shift, may be {@code null}.
7136 * @param startIndexInclusive
7137 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7138 * change.
7139 * @param endIndexExclusive
7140 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7141 * change. Overvalue (>array.length) is demoted to array length.
7142 * @param offset
7143 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7144 * rotate, than the effective offset is modulo the number of elements to rotate.
7145 * @since 3.5
7146 */
7147 public static void shift(final char[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7148 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7149 return;
7150 }
7151 startIndexInclusive = max0(startIndexInclusive);
7152 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7153 int n = endIndexExclusive - startIndexInclusive;
7154 if (n <= 1) {
7155 return;
7156 }
7157 offset %= n;
7158 if (offset < 0) {
7159 offset += n;
7160 }
7161 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7162 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7163 while (n > 1 && offset > 0) {
7164 final int nOffset = n - offset;
7165 if (offset > nOffset) {
7166 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7167 n = offset;
7168 offset -= nOffset;
7169 } else if (offset < nOffset) {
7170 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7171 startIndexInclusive += offset;
7172 n = nOffset;
7173 } else {
7174 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7175 break;
7176 }
7177 }
7178 }
7179
7180 /**
7181 * Shifts the order of the given double array.
7182 *
7183 * <p>There is no special handling for multi-dimensional arrays. This method
7184 * does nothing for {@code null} or empty input arrays.</p>
7185 *
7186 * @param array the array to shift, may be {@code null}.
7187 * @param offset
7188 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7189 * rotate, than the effective offset is modulo the number of elements to rotate.
7190 * @since 3.5
7191 */
7192 public static void shift(final double[] array, final int offset) {
7193 if (array != null) {
7194 shift(array, 0, array.length, offset);
7195 }
7196 }
7197
7198 /**
7199 * Shifts the order of a series of elements in the given double array.
7200 *
7201 * <p>There is no special handling for multi-dimensional arrays. This method
7202 * does nothing for {@code null} or empty input arrays.</p>
7203 *
7204 * @param array
7205 * the array to shift, may be {@code null}.
7206 * @param startIndexInclusive
7207 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7208 * change.
7209 * @param endIndexExclusive
7210 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7211 * change. Overvalue (>array.length) is demoted to array length.
7212 * @param offset
7213 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7214 * rotate, than the effective offset is modulo the number of elements to rotate.
7215 * @since 3.5
7216 */
7217 public static void shift(final double[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7218 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7219 return;
7220 }
7221 startIndexInclusive = max0(startIndexInclusive);
7222 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7223 int n = endIndexExclusive - startIndexInclusive;
7224 if (n <= 1) {
7225 return;
7226 }
7227 offset %= n;
7228 if (offset < 0) {
7229 offset += n;
7230 }
7231 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7232 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7233 while (n > 1 && offset > 0) {
7234 final int nOffset = n - offset;
7235 if (offset > nOffset) {
7236 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7237 n = offset;
7238 offset -= nOffset;
7239 } else if (offset < nOffset) {
7240 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7241 startIndexInclusive += offset;
7242 n = nOffset;
7243 } else {
7244 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7245 break;
7246 }
7247 }
7248 }
7249
7250 /**
7251 * Shifts the order of the given float array.
7252 *
7253 * <p>There is no special handling for multi-dimensional arrays. This method
7254 * does nothing for {@code null} or empty input arrays.</p>
7255 *
7256 * @param array the array to shift, may be {@code null}.
7257 * @param offset
7258 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7259 * rotate, than the effective offset is modulo the number of elements to rotate.
7260 * @since 3.5
7261 */
7262 public static void shift(final float[] array, final int offset) {
7263 if (array != null) {
7264 shift(array, 0, array.length, offset);
7265 }
7266 }
7267
7268 /**
7269 * Shifts the order of a series of elements in the given float array.
7270 *
7271 * <p>There is no special handling for multi-dimensional arrays. This method
7272 * does nothing for {@code null} or empty input arrays.</p>
7273 *
7274 * @param array
7275 * the array to shift, may be {@code null}.
7276 * @param startIndexInclusive
7277 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7278 * change.
7279 * @param endIndexExclusive
7280 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7281 * change. Overvalue (>array.length) is demoted to array length.
7282 * @param offset
7283 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7284 * rotate, than the effective offset is modulo the number of elements to rotate.
7285 * @since 3.5
7286 */
7287 public static void shift(final float[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7288 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7289 return;
7290 }
7291 startIndexInclusive = max0(startIndexInclusive);
7292 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7293 int n = endIndexExclusive - startIndexInclusive;
7294 if (n <= 1) {
7295 return;
7296 }
7297 offset %= n;
7298 if (offset < 0) {
7299 offset += n;
7300 }
7301 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7302 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7303 while (n > 1 && offset > 0) {
7304 final int nOffset = n - offset;
7305 if (offset > nOffset) {
7306 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7307 n = offset;
7308 offset -= nOffset;
7309 } else if (offset < nOffset) {
7310 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7311 startIndexInclusive += offset;
7312 n = nOffset;
7313 } else {
7314 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7315 break;
7316 }
7317 }
7318 }
7319
7320 /**
7321 * Shifts the order of the given int array.
7322 *
7323 * <p>There is no special handling for multi-dimensional arrays. This method
7324 * does nothing for {@code null} or empty input arrays.</p>
7325 *
7326 * @param array the array to shift, may be {@code null}.
7327 * @param offset
7328 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7329 * rotate, than the effective offset is modulo the number of elements to rotate.
7330 * @since 3.5
7331 */
7332 public static void shift(final int[] array, final int offset) {
7333 if (array != null) {
7334 shift(array, 0, array.length, offset);
7335 }
7336 }
7337
7338 /**
7339 * Shifts the order of a series of elements in the given int array.
7340 *
7341 * <p>There is no special handling for multi-dimensional arrays. This method
7342 * does nothing for {@code null} or empty input arrays.</p>
7343 *
7344 * @param array
7345 * the array to shift, may be {@code null}.
7346 * @param startIndexInclusive
7347 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7348 * change.
7349 * @param endIndexExclusive
7350 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7351 * change. Overvalue (>array.length) is demoted to array length.
7352 * @param offset
7353 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7354 * rotate, than the effective offset is modulo the number of elements to rotate.
7355 * @since 3.5
7356 */
7357 public static void shift(final int[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7358 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7359 return;
7360 }
7361 startIndexInclusive = max0(startIndexInclusive);
7362 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7363 int n = endIndexExclusive - startIndexInclusive;
7364 if (n <= 1) {
7365 return;
7366 }
7367 offset %= n;
7368 if (offset < 0) {
7369 offset += n;
7370 }
7371 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7372 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7373 while (n > 1 && offset > 0) {
7374 final int nOffset = n - offset;
7375 if (offset > nOffset) {
7376 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7377 n = offset;
7378 offset -= nOffset;
7379 } else if (offset < nOffset) {
7380 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7381 startIndexInclusive += offset;
7382 n = nOffset;
7383 } else {
7384 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7385 break;
7386 }
7387 }
7388 }
7389
7390 /**
7391 * Shifts the order of the given long array.
7392 *
7393 * <p>There is no special handling for multi-dimensional arrays. This method
7394 * does nothing for {@code null} or empty input arrays.</p>
7395 *
7396 * @param array the array to shift, may be {@code null}.
7397 * @param offset
7398 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7399 * rotate, than the effective offset is modulo the number of elements to rotate.
7400 * @since 3.5
7401 */
7402 public static void shift(final long[] array, final int offset) {
7403 if (array != null) {
7404 shift(array, 0, array.length, offset);
7405 }
7406 }
7407
7408 /**
7409 * Shifts the order of a series of elements in the given long array.
7410 *
7411 * <p>There is no special handling for multi-dimensional arrays. This method
7412 * does nothing for {@code null} or empty input arrays.</p>
7413 *
7414 * @param array
7415 * the array to shift, may be {@code null}.
7416 * @param startIndexInclusive
7417 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7418 * change.
7419 * @param endIndexExclusive
7420 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7421 * change. Overvalue (>array.length) is demoted to array length.
7422 * @param offset
7423 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7424 * rotate, than the effective offset is modulo the number of elements to rotate.
7425 * @since 3.5
7426 */
7427 public static void shift(final long[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7428 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7429 return;
7430 }
7431 startIndexInclusive = max0(startIndexInclusive);
7432 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7433 int n = endIndexExclusive - startIndexInclusive;
7434 if (n <= 1) {
7435 return;
7436 }
7437 offset %= n;
7438 if (offset < 0) {
7439 offset += n;
7440 }
7441 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7442 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7443 while (n > 1 && offset > 0) {
7444 final int nOffset = n - offset;
7445 if (offset > nOffset) {
7446 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7447 n = offset;
7448 offset -= nOffset;
7449 } else if (offset < nOffset) {
7450 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7451 startIndexInclusive += offset;
7452 n = nOffset;
7453 } else {
7454 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7455 break;
7456 }
7457 }
7458 }
7459
7460 /**
7461 * Shifts the order of the given array.
7462 *
7463 * <p>There is no special handling for multi-dimensional arrays. This method
7464 * does nothing for {@code null} or empty input arrays.</p>
7465 *
7466 * @param array the array to shift, may be {@code null}.
7467 * @param offset
7468 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7469 * rotate, than the effective offset is modulo the number of elements to rotate.
7470 * @since 3.5
7471 */
7472 public static void shift(final Object[] array, final int offset) {
7473 if (array != null) {
7474 shift(array, 0, array.length, offset);
7475 }
7476 }
7477
7478 /**
7479 * Shifts the order of a series of elements in the given array.
7480 *
7481 * <p>There is no special handling for multi-dimensional arrays. This method
7482 * does nothing for {@code null} or empty input arrays.</p>
7483 *
7484 * @param array
7485 * the array to shift, may be {@code null}.
7486 * @param startIndexInclusive
7487 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7488 * change.
7489 * @param endIndexExclusive
7490 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7491 * change. Overvalue (>array.length) is demoted to array length.
7492 * @param offset
7493 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7494 * rotate, than the effective offset is modulo the number of elements to rotate.
7495 * @since 3.5
7496 */
7497 public static void shift(final Object[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7498 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7499 return;
7500 }
7501 startIndexInclusive = max0(startIndexInclusive);
7502 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7503 int n = endIndexExclusive - startIndexInclusive;
7504 if (n <= 1) {
7505 return;
7506 }
7507 offset %= n;
7508 if (offset < 0) {
7509 offset += n;
7510 }
7511 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7512 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7513 while (n > 1 && offset > 0) {
7514 final int nOffset = n - offset;
7515 if (offset > nOffset) {
7516 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7517 n = offset;
7518 offset -= nOffset;
7519 } else if (offset < nOffset) {
7520 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7521 startIndexInclusive += offset;
7522 n = nOffset;
7523 } else {
7524 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7525 break;
7526 }
7527 }
7528 }
7529
7530 /**
7531 * Shifts the order of the given short array.
7532 *
7533 * <p>There is no special handling for multi-dimensional arrays. This method
7534 * does nothing for {@code null} or empty input arrays.</p>
7535 *
7536 * @param array the array to shift, may be {@code null}.
7537 * @param offset
7538 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7539 * rotate, than the effective offset is modulo the number of elements to rotate.
7540 * @since 3.5
7541 */
7542 public static void shift(final short[] array, final int offset) {
7543 if (array != null) {
7544 shift(array, 0, array.length, offset);
7545 }
7546 }
7547
7548 /**
7549 * Shifts the order of a series of elements in the given short array.
7550 *
7551 * <p>There is no special handling for multi-dimensional arrays. This method
7552 * does nothing for {@code null} or empty input arrays.</p>
7553 *
7554 * @param array
7555 * the array to shift, may be {@code null}.
7556 * @param startIndexInclusive
7557 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7558 * change.
7559 * @param endIndexExclusive
7560 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7561 * change. Overvalue (>array.length) is demoted to array length.
7562 * @param offset
7563 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7564 * rotate, than the effective offset is modulo the number of elements to rotate.
7565 * @since 3.5
7566 */
7567 public static void shift(final short[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7568 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7569 return;
7570 }
7571 startIndexInclusive = max0(startIndexInclusive);
7572 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7573 int n = endIndexExclusive - startIndexInclusive;
7574 if (n <= 1) {
7575 return;
7576 }
7577 offset %= n;
7578 if (offset < 0) {
7579 offset += n;
7580 }
7581 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7582 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7583 while (n > 1 && offset > 0) {
7584 final int nOffset = n - offset;
7585 if (offset > nOffset) {
7586 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7587 n = offset;
7588 offset -= nOffset;
7589 } else if (offset < nOffset) {
7590 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7591 startIndexInclusive += offset;
7592 n = nOffset;
7593 } else {
7594 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7595 break;
7596 }
7597 }
7598 }
7599
7600 /**
7601 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7602 * algorithm</a>.
7603 * <p>
7604 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7605 * </p>
7606 * <p>
7607 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7608 * with a {@link SecureRandom} argument.
7609 * </p>
7610 *
7611 * @param array the array to shuffle.
7612 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7613 * @since 3.6
7614 */
7615 public static void shuffle(final boolean[] array) {
7616 shuffle(array, random());
7617 }
7618
7619 /**
7620 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7621 * algorithm</a>.
7622 *
7623 * @param array the array to shuffle
7624 * @param random the source of randomness used to permute the elements
7625 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7626 * @since 3.6
7627 */
7628 public static void shuffle(final boolean[] array, final Random random) {
7629 for (int i = array.length; i > 1; i--) {
7630 swap(array, i - 1, random.nextInt(i), 1);
7631 }
7632 }
7633
7634 /**
7635 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7636 * algorithm</a>.
7637 * <p>
7638 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7639 * </p>
7640 * <p>
7641 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7642 * with a {@link SecureRandom} argument.
7643 * </p>
7644 *
7645 * @param array the array to shuffle.
7646 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7647 * @since 3.6
7648 */
7649 public static void shuffle(final byte[] array) {
7650 shuffle(array, random());
7651 }
7652
7653 /**
7654 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7655 * algorithm</a>.
7656 *
7657 * @param array the array to shuffle
7658 * @param random the source of randomness used to permute the elements
7659 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7660 * @since 3.6
7661 */
7662 public static void shuffle(final byte[] array, final Random random) {
7663 for (int i = array.length; i > 1; i--) {
7664 swap(array, i - 1, random.nextInt(i), 1);
7665 }
7666 }
7667
7668 /**
7669 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7670 * algorithm</a>.
7671 * <p>
7672 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7673 * </p>
7674 * <p>
7675 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7676 * with a {@link SecureRandom} argument.
7677 * </p>
7678 *
7679 * @param array the array to shuffle.
7680 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7681 * @since 3.6
7682 */
7683 public static void shuffle(final char[] array) {
7684 shuffle(array, random());
7685 }
7686
7687 /**
7688 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7689 * algorithm</a>.
7690 *
7691 * @param array the array to shuffle
7692 * @param random the source of randomness used to permute the elements
7693 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7694 * @since 3.6
7695 */
7696 public static void shuffle(final char[] array, final Random random) {
7697 for (int i = array.length; i > 1; i--) {
7698 swap(array, i - 1, random.nextInt(i), 1);
7699 }
7700 }
7701
7702 /**
7703 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7704 * algorithm</a>.
7705 * <p>
7706 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7707 * </p>
7708 * <p>
7709 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7710 * with a {@link SecureRandom} argument.
7711 * </p>
7712 *
7713 * @param array the array to shuffle.
7714 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7715 * @since 3.6
7716 */
7717 public static void shuffle(final double[] array) {
7718 shuffle(array, random());
7719 }
7720
7721 /**
7722 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7723 * algorithm</a>.
7724 *
7725 * @param array the array to shuffle
7726 * @param random the source of randomness used to permute the elements
7727 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7728 * @since 3.6
7729 */
7730 public static void shuffle(final double[] array, final Random random) {
7731 for (int i = array.length; i > 1; i--) {
7732 swap(array, i - 1, random.nextInt(i), 1);
7733 }
7734 }
7735
7736 /**
7737 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7738 * algorithm</a>.
7739 * <p>
7740 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7741 * </p>
7742 * <p>
7743 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7744 * with a {@link SecureRandom} argument.
7745 * </p>
7746 *
7747 * @param array the array to shuffle.
7748 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7749 * @since 3.6
7750 */
7751 public static void shuffle(final float[] array) {
7752 shuffle(array, random());
7753 }
7754
7755 /**
7756 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7757 * algorithm</a>.
7758 *
7759 * @param array the array to shuffle
7760 * @param random the source of randomness used to permute the elements
7761 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7762 * @since 3.6
7763 */
7764 public static void shuffle(final float[] array, final Random random) {
7765 for (int i = array.length; i > 1; i--) {
7766 swap(array, i - 1, random.nextInt(i), 1);
7767 }
7768 }
7769
7770 /**
7771 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7772 * algorithm</a>.
7773 * <p>
7774 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7775 * </p>
7776 * <p>
7777 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7778 * with a {@link SecureRandom} argument.
7779 * </p>
7780 *
7781 * @param array the array to shuffle.
7782 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7783 * @since 3.6
7784 */
7785 public static void shuffle(final int[] array) {
7786 shuffle(array, random());
7787 }
7788
7789 /**
7790 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7791 * algorithm</a>.
7792 *
7793 * @param array the array to shuffle
7794 * @param random the source of randomness used to permute the elements
7795 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7796 * @since 3.6
7797 */
7798 public static void shuffle(final int[] array, final Random random) {
7799 for (int i = array.length; i > 1; i--) {
7800 swap(array, i - 1, random.nextInt(i), 1);
7801 }
7802 }
7803
7804 /**
7805 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7806 * algorithm</a>.
7807 * <p>
7808 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7809 * </p>
7810 * <p>
7811 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7812 * with a {@link SecureRandom} argument.
7813 * </p>
7814 *
7815 * @param array the array to shuffle.
7816 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7817 * @since 3.6
7818 */
7819 public static void shuffle(final long[] array) {
7820 shuffle(array, random());
7821 }
7822
7823 /**
7824 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7825 * algorithm</a>.
7826 *
7827 * @param array the array to shuffle
7828 * @param random the source of randomness used to permute the elements
7829 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7830 * @since 3.6
7831 */
7832 public static void shuffle(final long[] array, final Random random) {
7833 for (int i = array.length; i > 1; i--) {
7834 swap(array, i - 1, random.nextInt(i), 1);
7835 }
7836 }
7837
7838 /**
7839 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7840 * algorithm</a>.
7841 * <p>
7842 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7843 * </p>
7844 * <p>
7845 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7846 * with a {@link SecureRandom} argument.
7847 * </p>
7848 *
7849 * @param array the array to shuffle.
7850 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7851 * @since 3.6
7852 */
7853 public static void shuffle(final Object[] array) {
7854 shuffle(array, random());
7855 }
7856
7857 /**
7858 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7859 * algorithm</a>.
7860 *
7861 * @param array the array to shuffle
7862 * @param random the source of randomness used to permute the elements
7863 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7864 * @since 3.6
7865 */
7866 public static void shuffle(final Object[] array, final Random random) {
7867 for (int i = array.length; i > 1; i--) {
7868 swap(array, i - 1, random.nextInt(i), 1);
7869 }
7870 }
7871
7872 /**
7873 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7874 * algorithm</a>.
7875 * <p>
7876 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7877 * </p>
7878 * <p>
7879 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7880 * with a {@link SecureRandom} argument.
7881 * </p>
7882 *
7883 * @param array the array to shuffle.
7884 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7885 * @since 3.6
7886 */
7887 public static void shuffle(final short[] array) {
7888 shuffle(array, random());
7889 }
7890
7891 /**
7892 * Shuffles randomly the elements of the specified array using the <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle
7893 * algorithm</a>.
7894 *
7895 * @param array the array to shuffle
7896 * @param random the source of randomness used to permute the elements
7897 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7898 * @since 3.6
7899 */
7900 public static void shuffle(final short[] array, final Random random) {
7901 for (int i = array.length; i > 1; i--) {
7902 swap(array, i - 1, random.nextInt(i), 1);
7903 }
7904 }
7905
7906 /**
7907 * Tests whether the given data array starts with an expected array, for example, signature bytes.
7908 * <p>
7909 * If both arrays are null, the method returns true. The method return false when one array is null and the other not.
7910 * </p>
7911 *
7912 * @param data The data to search, maybe larger than the expected data.
7913 * @param expected The expected data to find.
7914 * @return whether a match was found.
7915 * @since 3.18.0
7916 */
7917 public static boolean startsWith(final byte[] data, final byte[] expected) {
7918 if (data == expected) {
7919 return true;
7920 }
7921 if (data == null || expected == null) {
7922 return false;
7923 }
7924 final int dataLen = data.length;
7925 if (expected.length > dataLen) {
7926 return false;
7927 }
7928 if (expected.length == dataLen) {
7929 // delegate to Arrays.equals() which has optimizations on Java > 8
7930 return Arrays.equals(data, expected);
7931 }
7932 // Once we are on Java 9+ we can delegate to Arrays here as well (or not).
7933 for (int i = 0; i < expected.length; i++) {
7934 if (data[i] != expected[i]) {
7935 return false;
7936 }
7937 }
7938 return true;
7939 }
7940
7941 /**
7942 * Produces a new {@code boolean} array containing the elements
7943 * between the start and end indices.
7944 * <p>
7945 * The start index is inclusive, the end index exclusive.
7946 * Null array input produces null output.
7947 * </p>
7948 *
7949 * @param array the array
7950 * @param startIndexInclusive the starting index. Undervalue (<0)
7951 * is promoted to 0, overvalue (>array.length) results
7952 * in an empty array.
7953 * @param endIndexExclusive elements up to endIndex-1 are present in the
7954 * returned subarray. Undervalue (< startIndex) produces
7955 * empty array, overvalue (>array.length) is demoted to
7956 * array length.
7957 * @return a new array containing the elements between
7958 * the start and end indices.
7959 * @since 2.1
7960 * @see Arrays#copyOfRange(boolean[], int, int)
7961 */
7962 public static boolean[] subarray(final boolean[] array, int startIndexInclusive, int endIndexExclusive) {
7963 if (array == null) {
7964 return null;
7965 }
7966 startIndexInclusive = max0(startIndexInclusive);
7967 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7968 final int newSize = endIndexExclusive - startIndexInclusive;
7969 if (newSize <= 0) {
7970 return EMPTY_BOOLEAN_ARRAY;
7971 }
7972 return arraycopy(array, startIndexInclusive, 0, newSize, boolean[]::new);
7973 }
7974
7975 /**
7976 * Produces a new {@code byte} array containing the elements
7977 * between the start and end indices.
7978 * <p>
7979 * The start index is inclusive, the end index exclusive.
7980 * Null array input produces null output.
7981 * </p>
7982 *
7983 * @param array the array
7984 * @param startIndexInclusive the starting index. Undervalue (<0)
7985 * is promoted to 0, overvalue (>array.length) results
7986 * in an empty array.
7987 * @param endIndexExclusive elements up to endIndex-1 are present in the
7988 * returned subarray. Undervalue (< startIndex) produces
7989 * empty array, overvalue (>array.length) is demoted to
7990 * array length.
7991 * @return a new array containing the elements between
7992 * the start and end indices.
7993 * @since 2.1
7994 * @see Arrays#copyOfRange(byte[], int, int)
7995 */
7996 public static byte[] subarray(final byte[] array, int startIndexInclusive, int endIndexExclusive) {
7997 if (array == null) {
7998 return null;
7999 }
8000 startIndexInclusive = max0(startIndexInclusive);
8001 endIndexExclusive = Math.min(endIndexExclusive, array.length);
8002 final int newSize = endIndexExclusive - startIndexInclusive;
8003 if (newSize <= 0) {
8004 return EMPTY_BYTE_ARRAY;
8005 }
8006 return arraycopy(array, startIndexInclusive, 0, newSize, byte[]::new);
8007 }
8008
8009 /**
8010 * Produces a new {@code char} array containing the elements
8011 * between the start and end indices.
8012 * <p>
8013 * The start index is inclusive, the end index exclusive.
8014 * Null array input produces null output.
8015 * </p>
8016 *
8017 * @param array the array
8018 * @param startIndexInclusive the starting index. Undervalue (<0)
8019 * is promoted to 0, overvalue (>array.length) results
8020 * in an empty array.
8021 * @param endIndexExclusive elements up to endIndex-1 are present in the
8022 * returned subarray. Undervalue (< startIndex) produces
8023 * empty array, overvalue (>array.length) is demoted to
8024 * array length.
8025 * @return a new array containing the elements between
8026 * the start and end indices.
8027 * @since 2.1
8028 * @see Arrays#copyOfRange(char[], int, int)
8029 */
8030 public static char[] subarray(final char[] array, int startIndexInclusive, int endIndexExclusive) {
8031 if (array == null) {
8032 return null;
8033 }
8034 startIndexInclusive = max0(startIndexInclusive);
8035 endIndexExclusive = Math.min(endIndexExclusive, array.length);
8036 final int newSize = endIndexExclusive - startIndexInclusive;
8037 if (newSize <= 0) {
8038 return EMPTY_CHAR_ARRAY;
8039 }
8040 return arraycopy(array, startIndexInclusive, 0, newSize, char[]::new);
8041 }
8042
8043 /**
8044 * Produces a new {@code double} array containing the elements
8045 * between the start and end indices.
8046 * <p>
8047 * The start index is inclusive, the end index exclusive.
8048 * Null array input produces null output.
8049 * </p>
8050 *
8051 * @param array the array
8052 * @param startIndexInclusive the starting index. Undervalue (<0)
8053 * is promoted to 0, overvalue (>array.length) results
8054 * in an empty array.
8055 * @param endIndexExclusive elements up to endIndex-1 are present in the
8056 * returned subarray. Undervalue (< startIndex) produces
8057 * empty array, overvalue (>array.length) is demoted to
8058 * array length.
8059 * @return a new array containing the elements between
8060 * the start and end indices.
8061 * @since 2.1
8062 * @see Arrays#copyOfRange(double[], int, int)
8063 */
8064 public static double[] subarray(final double[] array, int startIndexInclusive, int endIndexExclusive) {
8065 if (array == null) {
8066 return null;
8067 }
8068 startIndexInclusive = max0(startIndexInclusive);
8069 endIndexExclusive = Math.min(endIndexExclusive, array.length);
8070 final int newSize = endIndexExclusive - startIndexInclusive;
8071 if (newSize <= 0) {
8072 return EMPTY_DOUBLE_ARRAY;
8073 }
8074 return arraycopy(array, startIndexInclusive, 0, newSize, double[]::new);
8075 }
8076
8077 /**
8078 * Produces a new {@code float} array containing the elements
8079 * between the start and end indices.
8080 * <p>
8081 * The start index is inclusive, the end index exclusive.
8082 * Null array input produces null output.
8083 * </p>
8084 *
8085 * @param array the array
8086 * @param startIndexInclusive the starting index. Undervalue (<0)
8087 * is promoted to 0, overvalue (>array.length) results
8088 * in an empty array.
8089 * @param endIndexExclusive elements up to endIndex-1 are present in the
8090 * returned subarray. Undervalue (< startIndex) produces
8091 * empty array, overvalue (>array.length) is demoted to
8092 * array length.
8093 * @return a new array containing the elements between
8094 * the start and end indices.
8095 * @since 2.1
8096 * @see Arrays#copyOfRange(float[], int, int)
8097 */
8098 public static float[] subarray(final float[] array, int startIndexInclusive, int endIndexExclusive) {
8099 if (array == null) {
8100 return null;
8101 }
8102 startIndexInclusive = max0(startIndexInclusive);
8103 endIndexExclusive = Math.min(endIndexExclusive, array.length);
8104 final int newSize = endIndexExclusive - startIndexInclusive;
8105 if (newSize <= 0) {
8106 return EMPTY_FLOAT_ARRAY;
8107 }
8108 return arraycopy(array, startIndexInclusive, 0, newSize, float[]::new);
8109 }
8110
8111 /**
8112 * Produces a new {@code int} array containing the elements
8113 * between the start and end indices.
8114 * <p>
8115 * The start index is inclusive, the end index exclusive.
8116 * Null array input produces null output.
8117 * </p>
8118 *
8119 * @param array the array
8120 * @param startIndexInclusive the starting index. Undervalue (<0)
8121 * is promoted to 0, overvalue (>array.length) results
8122 * in an empty array.
8123 * @param endIndexExclusive elements up to endIndex-1 are present in the
8124 * returned subarray. Undervalue (< startIndex) produces
8125 * empty array, overvalue (>array.length) is demoted to
8126 * array length.
8127 * @return a new array containing the elements between
8128 * the start and end indices.
8129 * @since 2.1
8130 * @see Arrays#copyOfRange(int[], int, int)
8131 */
8132 public static int[] subarray(final int[] array, int startIndexInclusive, int endIndexExclusive) {
8133 if (array == null) {
8134 return null;
8135 }
8136 startIndexInclusive = max0(startIndexInclusive);
8137 endIndexExclusive = Math.min(endIndexExclusive, array.length);
8138 final int newSize = endIndexExclusive - startIndexInclusive;
8139 if (newSize <= 0) {
8140 return EMPTY_INT_ARRAY;
8141 }
8142 return arraycopy(array, startIndexInclusive, 0, newSize, int[]::new);
8143 }
8144
8145 /**
8146 * Produces a new {@code long} array containing the elements
8147 * between the start and end indices.
8148 * <p>
8149 * The start index is inclusive, the end index exclusive.
8150 * Null array input produces null output.
8151 * </p>
8152 *
8153 * @param array the array
8154 * @param startIndexInclusive the starting index. Undervalue (<0)
8155 * is promoted to 0, overvalue (>array.length) results
8156 * in an empty array.
8157 * @param endIndexExclusive elements up to endIndex-1 are present in the
8158 * returned subarray. Undervalue (< startIndex) produces
8159 * empty array, overvalue (>array.length) is demoted to
8160 * array length.
8161 * @return a new array containing the elements between
8162 * the start and end indices.
8163 * @since 2.1
8164 * @see Arrays#copyOfRange(long[], int, int)
8165 */
8166 public static long[] subarray(final long[] array, int startIndexInclusive, int endIndexExclusive) {
8167 if (array == null) {
8168 return null;
8169 }
8170 startIndexInclusive = max0(startIndexInclusive);
8171 endIndexExclusive = Math.min(endIndexExclusive, array.length);
8172 final int newSize = endIndexExclusive - startIndexInclusive;
8173 if (newSize <= 0) {
8174 return EMPTY_LONG_ARRAY;
8175 }
8176 return arraycopy(array, startIndexInclusive, 0, newSize, long[]::new);
8177 }
8178
8179 /**
8180 * Produces a new {@code short} array containing the elements
8181 * between the start and end indices.
8182 * <p>
8183 * The start index is inclusive, the end index exclusive.
8184 * Null array input produces null output.
8185 * </p>
8186 *
8187 * @param array the array
8188 * @param startIndexInclusive the starting index. Undervalue (<0)
8189 * is promoted to 0, overvalue (>array.length) results
8190 * in an empty array.
8191 * @param endIndexExclusive elements up to endIndex-1 are present in the
8192 * returned subarray. Undervalue (< startIndex) produces
8193 * empty array, overvalue (>array.length) is demoted to
8194 * array length.
8195 * @return a new array containing the elements between
8196 * the start and end indices.
8197 * @since 2.1
8198 * @see Arrays#copyOfRange(short[], int, int)
8199 */
8200 public static short[] subarray(final short[] array, int startIndexInclusive, int endIndexExclusive) {
8201 if (array == null) {
8202 return null;
8203 }
8204 startIndexInclusive = max0(startIndexInclusive);
8205 endIndexExclusive = Math.min(endIndexExclusive, array.length);
8206 final int newSize = endIndexExclusive - startIndexInclusive;
8207 if (newSize <= 0) {
8208 return EMPTY_SHORT_ARRAY;
8209 }
8210 return arraycopy(array, startIndexInclusive, 0, newSize, short[]::new);
8211 }
8212
8213 /**
8214 * Produces a new array containing the elements between
8215 * the start and end indices.
8216 * <p>
8217 * The start index is inclusive, the end index exclusive.
8218 * Null array input produces null output.
8219 * </p>
8220 * <p>
8221 * The component type of the subarray is always the same as
8222 * that of the input array. Thus, if the input is an array of type
8223 * {@link Date}, the following usage is envisaged:
8224 * </p>
8225 * <pre>
8226 * Date[] someDates = (Date[]) ArrayUtils.subarray(allDates, 2, 5);
8227 * </pre>
8228 *
8229 * @param <T> the component type of the array
8230 * @param array the array
8231 * @param startIndexInclusive the starting index. Undervalue (<0)
8232 * is promoted to 0, overvalue (>array.length) results
8233 * in an empty array.
8234 * @param endIndexExclusive elements up to endIndex-1 are present in the
8235 * returned subarray. Undervalue (< startIndex) produces
8236 * empty array, overvalue (>array.length) is demoted to
8237 * array length.
8238 * @return a new array containing the elements between
8239 * the start and end indices.
8240 * @since 2.1
8241 * @see Arrays#copyOfRange(Object[], int, int)
8242 */
8243 public static <T> T[] subarray(final T[] array, int startIndexInclusive, int endIndexExclusive) {
8244 if (array == null) {
8245 return null;
8246 }
8247 startIndexInclusive = max0(startIndexInclusive);
8248 endIndexExclusive = Math.min(endIndexExclusive, array.length);
8249 final int newSize = endIndexExclusive - startIndexInclusive;
8250 final Class<T> type = getComponentType(array);
8251 if (newSize <= 0) {
8252 return newInstance(type, 0);
8253 }
8254 return arraycopy(array, startIndexInclusive, 0, newSize, () -> newInstance(type, newSize));
8255 }
8256
8257 /**
8258 * Swaps two elements in the given boolean array.
8259 *
8260 * <p>There is no special handling for multi-dimensional arrays. This method
8261 * does nothing for a {@code null} or empty input array or for overflow indices.
8262 * Negative indices are promoted to 0(zero).</p>
8263 *
8264 * Examples:
8265 * <ul>
8266 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8267 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8268 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8269 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8270 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8271 * </ul>
8272 *
8273 * @param array the array to swap, may be {@code null}.
8274 * @param offset1 the index of the first element to swap
8275 * @param offset2 the index of the second element to swap
8276 * @since 3.5
8277 */
8278 public static void swap(final boolean[] array, final int offset1, final int offset2) {
8279 swap(array, offset1, offset2, 1);
8280 }
8281
8282 /**
8283 * Swaps a series of elements in the given boolean array.
8284 *
8285 * <p>This method does nothing for a {@code null} or empty input array or
8286 * for overflow indices. Negative indices are promoted to 0(zero). If any
8287 * of the sub-arrays to swap falls outside of the given array, then the
8288 * swap is stopped at the end of the array and as many as possible elements
8289 * are swapped.</p>
8290 *
8291 * Examples:
8292 * <ul>
8293 * <li>ArrayUtils.swap([true, false, true, false], 0, 2, 1) -> [true, false, true, false]</li>
8294 * <li>ArrayUtils.swap([true, false, true, false], 0, 0, 1) -> [true, false, true, false]</li>
8295 * <li>ArrayUtils.swap([true, false, true, false], 0, 2, 2) -> [true, false, true, false]</li>
8296 * <li>ArrayUtils.swap([true, false, true, false], -3, 2, 2) -> [true, false, true, false]</li>
8297 * <li>ArrayUtils.swap([true, false, true, false], 0, 3, 3) -> [false, false, true, true]</li>
8298 * </ul>
8299 *
8300 * @param array the array to swap, may be {@code null}.
8301 * @param offset1 the index of the first element in the series to swap
8302 * @param offset2 the index of the second element in the series to swap
8303 * @param len the number of elements to swap starting with the given indices
8304 * @since 3.5
8305 */
8306 public static void swap(final boolean[] array, int offset1, int offset2, int len) {
8307 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8308 return;
8309 }
8310 offset1 = max0(offset1);
8311 offset2 = max0(offset2);
8312 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8313 for (int i = 0; i < len; i++, offset1++, offset2++) {
8314 final boolean aux = array[offset1];
8315 array[offset1] = array[offset2];
8316 array[offset2] = aux;
8317 }
8318 }
8319
8320 /**
8321 * Swaps two elements in the given byte array.
8322 *
8323 * <p>There is no special handling for multi-dimensional arrays. This method
8324 * does nothing for a {@code null} or empty input array or for overflow indices.
8325 * Negative indices are promoted to 0(zero).</p>
8326 *
8327 * Examples:
8328 * <ul>
8329 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8330 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8331 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8332 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8333 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8334 * </ul>
8335 *
8336 * @param array the array to swap, may be {@code null}.
8337 * @param offset1 the index of the first element to swap
8338 * @param offset2 the index of the second element to swap
8339 * @since 3.5
8340 */
8341 public static void swap(final byte[] array, final int offset1, final int offset2) {
8342 swap(array, offset1, offset2, 1);
8343 }
8344
8345 /**
8346 * Swaps a series of elements in the given byte array.
8347 *
8348 * <p>This method does nothing for a {@code null} or empty input array or
8349 * for overflow indices. Negative indices are promoted to 0(zero). If any
8350 * of the sub-arrays to swap falls outside of the given array, then the
8351 * swap is stopped at the end of the array and as many as possible elements
8352 * are swapped.</p>
8353 *
8354 * Examples:
8355 * <ul>
8356 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8357 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8358 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8359 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8360 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8361 * </ul>
8362 *
8363 * @param array the array to swap, may be {@code null}.
8364 * @param offset1 the index of the first element in the series to swap
8365 * @param offset2 the index of the second element in the series to swap
8366 * @param len the number of elements to swap starting with the given indices
8367 * @since 3.5
8368 */
8369 public static void swap(final byte[] array, int offset1, int offset2, int len) {
8370 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8371 return;
8372 }
8373 offset1 = max0(offset1);
8374 offset2 = max0(offset2);
8375 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8376 for (int i = 0; i < len; i++, offset1++, offset2++) {
8377 final byte aux = array[offset1];
8378 array[offset1] = array[offset2];
8379 array[offset2] = aux;
8380 }
8381 }
8382
8383 /**
8384 * Swaps two elements in the given char array.
8385 *
8386 * <p>There is no special handling for multi-dimensional arrays. This method
8387 * does nothing for a {@code null} or empty input array or for overflow indices.
8388 * Negative indices are promoted to 0(zero).</p>
8389 *
8390 * Examples:
8391 * <ul>
8392 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8393 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8394 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8395 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8396 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8397 * </ul>
8398 *
8399 * @param array the array to swap, may be {@code null}.
8400 * @param offset1 the index of the first element to swap
8401 * @param offset2 the index of the second element to swap
8402 * @since 3.5
8403 */
8404 public static void swap(final char[] array, final int offset1, final int offset2) {
8405 swap(array, offset1, offset2, 1);
8406 }
8407
8408 /**
8409 * Swaps a series of elements in the given char array.
8410 *
8411 * <p>This method does nothing for a {@code null} or empty input array or
8412 * for overflow indices. Negative indices are promoted to 0(zero). If any
8413 * of the sub-arrays to swap falls outside of the given array, then the
8414 * swap is stopped at the end of the array and as many as possible elements
8415 * are swapped.</p>
8416 *
8417 * Examples:
8418 * <ul>
8419 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8420 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8421 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8422 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8423 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8424 * </ul>
8425 *
8426 * @param array the array to swap, may be {@code null}.
8427 * @param offset1 the index of the first element in the series to swap
8428 * @param offset2 the index of the second element in the series to swap
8429 * @param len the number of elements to swap starting with the given indices
8430 * @since 3.5
8431 */
8432 public static void swap(final char[] array, int offset1, int offset2, int len) {
8433 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8434 return;
8435 }
8436 offset1 = max0(offset1);
8437 offset2 = max0(offset2);
8438 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8439 for (int i = 0; i < len; i++, offset1++, offset2++) {
8440 final char aux = array[offset1];
8441 array[offset1] = array[offset2];
8442 array[offset2] = aux;
8443 }
8444 }
8445
8446 /**
8447 * Swaps two elements in the given double array.
8448 *
8449 * <p>There is no special handling for multi-dimensional arrays. This method
8450 * does nothing for a {@code null} or empty input array or for overflow indices.
8451 * Negative indices are promoted to 0(zero).</p>
8452 *
8453 * Examples:
8454 * <ul>
8455 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8456 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8457 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8458 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8459 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8460 * </ul>
8461 *
8462 * @param array the array to swap, may be {@code null}.
8463 * @param offset1 the index of the first element to swap
8464 * @param offset2 the index of the second element to swap
8465 * @since 3.5
8466 */
8467 public static void swap(final double[] array, final int offset1, final int offset2) {
8468 swap(array, offset1, offset2, 1);
8469 }
8470
8471 /**
8472 * Swaps a series of elements in the given double array.
8473 *
8474 * <p>This method does nothing for a {@code null} or empty input array or
8475 * for overflow indices. Negative indices are promoted to 0(zero). If any
8476 * of the sub-arrays to swap falls outside of the given array, then the
8477 * swap is stopped at the end of the array and as many as possible elements
8478 * are swapped.</p>
8479 *
8480 * Examples:
8481 * <ul>
8482 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8483 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8484 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8485 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8486 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8487 * </ul>
8488 *
8489 * @param array the array to swap, may be {@code null}.
8490 * @param offset1 the index of the first element in the series to swap
8491 * @param offset2 the index of the second element in the series to swap
8492 * @param len the number of elements to swap starting with the given indices
8493 * @since 3.5
8494 */
8495 public static void swap(final double[] array, int offset1, int offset2, int len) {
8496 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8497 return;
8498 }
8499 offset1 = max0(offset1);
8500 offset2 = max0(offset2);
8501 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8502 for (int i = 0; i < len; i++, offset1++, offset2++) {
8503 final double aux = array[offset1];
8504 array[offset1] = array[offset2];
8505 array[offset2] = aux;
8506 }
8507 }
8508
8509 /**
8510 * Swaps two elements in the given float array.
8511 *
8512 * <p>There is no special handling for multi-dimensional arrays. This method
8513 * does nothing for a {@code null} or empty input array or for overflow indices.
8514 * Negative indices are promoted to 0(zero).</p>
8515 *
8516 * Examples:
8517 * <ul>
8518 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8519 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8520 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8521 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8522 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8523 * </ul>
8524 *
8525 * @param array the array to swap, may be {@code null}.
8526 * @param offset1 the index of the first element to swap
8527 * @param offset2 the index of the second element to swap
8528 * @since 3.5
8529 */
8530 public static void swap(final float[] array, final int offset1, final int offset2) {
8531 swap(array, offset1, offset2, 1);
8532 }
8533
8534 /**
8535 * Swaps a series of elements in the given float array.
8536 *
8537 * <p>This method does nothing for a {@code null} or empty input array or
8538 * for overflow indices. Negative indices are promoted to 0(zero). If any
8539 * of the sub-arrays to swap falls outside of the given array, then the
8540 * swap is stopped at the end of the array and as many as possible elements
8541 * are swapped.</p>
8542 *
8543 * Examples:
8544 * <ul>
8545 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8546 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8547 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8548 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8549 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8550 * </ul>
8551 *
8552 * @param array the array to swap, may be {@code null}.
8553 * @param offset1 the index of the first element in the series to swap
8554 * @param offset2 the index of the second element in the series to swap
8555 * @param len the number of elements to swap starting with the given indices
8556 * @since 3.5
8557 */
8558 public static void swap(final float[] array, int offset1, int offset2, int len) {
8559 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8560 return;
8561 }
8562 offset1 = max0(offset1);
8563 offset2 = max0(offset2);
8564 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8565 for (int i = 0; i < len; i++, offset1++, offset2++) {
8566 final float aux = array[offset1];
8567 array[offset1] = array[offset2];
8568 array[offset2] = aux;
8569 }
8570
8571 }
8572
8573 /**
8574 * Swaps two elements in the given int array.
8575 *
8576 * <p>There is no special handling for multi-dimensional arrays. This method
8577 * does nothing for a {@code null} or empty input array or for overflow indices.
8578 * Negative indices are promoted to 0(zero).</p>
8579 *
8580 * Examples:
8581 * <ul>
8582 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8583 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8584 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8585 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8586 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8587 * </ul>
8588 *
8589 * @param array the array to swap, may be {@code null}
8590 * @param offset1 the index of the first element to swap
8591 * @param offset2 the index of the second element to swap
8592 * @since 3.5
8593 */
8594 public static void swap(final int[] array, final int offset1, final int offset2) {
8595 swap(array, offset1, offset2, 1);
8596 }
8597
8598 /**
8599 * Swaps a series of elements in the given int array.
8600 *
8601 * <p>This method does nothing for a {@code null} or empty input array or
8602 * for overflow indices. Negative indices are promoted to 0(zero). If any
8603 * of the sub-arrays to swap falls outside of the given array, then the
8604 * swap is stopped at the end of the array and as many as possible elements
8605 * are swapped.</p>
8606 *
8607 * Examples:
8608 * <ul>
8609 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8610 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8611 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8612 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8613 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8614 * </ul>
8615 *
8616 * @param array the array to swap, may be {@code null}
8617 * @param offset1 the index of the first element in the series to swap
8618 * @param offset2 the index of the second element in the series to swap
8619 * @param len the number of elements to swap starting with the given indices
8620 * @since 3.5
8621 */
8622 public static void swap(final int[] array, int offset1, int offset2, int len) {
8623 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8624 return;
8625 }
8626 offset1 = max0(offset1);
8627 offset2 = max0(offset2);
8628 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8629 for (int i = 0; i < len; i++, offset1++, offset2++) {
8630 final int aux = array[offset1];
8631 array[offset1] = array[offset2];
8632 array[offset2] = aux;
8633 }
8634 }
8635
8636 /**
8637 * Swaps two elements in the given long array.
8638 *
8639 * <p>There is no special handling for multi-dimensional arrays. This method
8640 * does nothing for a {@code null} or empty input array or for overflow indices.
8641 * Negative indices are promoted to 0(zero).</p>
8642 *
8643 * Examples:
8644 * <ul>
8645 * <li>ArrayUtils.swap([true, false, true], 0, 2) -> [true, false, true]</li>
8646 * <li>ArrayUtils.swap([true, false, true], 0, 0) -> [true, false, true]</li>
8647 * <li>ArrayUtils.swap([true, false, true], 1, 0) -> [false, true, true]</li>
8648 * <li>ArrayUtils.swap([true, false, true], 0, 5) -> [true, false, true]</li>
8649 * <li>ArrayUtils.swap([true, false, true], -1, 1) -> [false, true, true]</li>
8650 * </ul>
8651 *
8652 * @param array the array to swap, may be {@code null}
8653 * @param offset1 the index of the first element to swap
8654 * @param offset2 the index of the second element to swap
8655 * @since 3.5
8656 */
8657 public static void swap(final long[] array, final int offset1, final int offset2) {
8658 swap(array, offset1, offset2, 1);
8659 }
8660
8661 /**
8662 * Swaps a series of elements in the given long array.
8663 *
8664 * <p>This method does nothing for a {@code null} or empty input array or
8665 * for overflow indices. Negative indices are promoted to 0(zero). If any
8666 * of the sub-arrays to swap falls outside of the given array, then the
8667 * swap is stopped at the end of the array and as many as possible elements
8668 * are swapped.</p>
8669 *
8670 * Examples:
8671 * <ul>
8672 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8673 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8674 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8675 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8676 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8677 * </ul>
8678 *
8679 * @param array the array to swap, may be {@code null}
8680 * @param offset1 the index of the first element in the series to swap
8681 * @param offset2 the index of the second element in the series to swap
8682 * @param len the number of elements to swap starting with the given indices
8683 * @since 3.5
8684 */
8685 public static void swap(final long[] array, int offset1, int offset2, int len) {
8686 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8687 return;
8688 }
8689 offset1 = max0(offset1);
8690 offset2 = max0(offset2);
8691 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8692 for (int i = 0; i < len; i++, offset1++, offset2++) {
8693 final long aux = array[offset1];
8694 array[offset1] = array[offset2];
8695 array[offset2] = aux;
8696 }
8697 }
8698
8699 /**
8700 * Swaps two elements in the given array.
8701 *
8702 * <p>There is no special handling for multi-dimensional arrays. This method
8703 * does nothing for a {@code null} or empty input array or for overflow indices.
8704 * Negative indices are promoted to 0(zero).</p>
8705 *
8706 * Examples:
8707 * <ul>
8708 * <li>ArrayUtils.swap(["1", "2", "3"], 0, 2) -> ["3", "2", "1"]</li>
8709 * <li>ArrayUtils.swap(["1", "2", "3"], 0, 0) -> ["1", "2", "3"]</li>
8710 * <li>ArrayUtils.swap(["1", "2", "3"], 1, 0) -> ["2", "1", "3"]</li>
8711 * <li>ArrayUtils.swap(["1", "2", "3"], 0, 5) -> ["1", "2", "3"]</li>
8712 * <li>ArrayUtils.swap(["1", "2", "3"], -1, 1) -> ["2", "1", "3"]</li>
8713 * </ul>
8714 *
8715 * @param array the array to swap, may be {@code null}
8716 * @param offset1 the index of the first element to swap
8717 * @param offset2 the index of the second element to swap
8718 * @since 3.5
8719 */
8720 public static void swap(final Object[] array, final int offset1, final int offset2) {
8721 swap(array, offset1, offset2, 1);
8722 }
8723
8724 /**
8725 * Swaps a series of elements in the given array.
8726 *
8727 * <p>This method does nothing for a {@code null} or empty input array or
8728 * for overflow indices. Negative indices are promoted to 0(zero). If any
8729 * of the sub-arrays to swap falls outside of the given array, then the
8730 * swap is stopped at the end of the array and as many as possible elements
8731 * are swapped.</p>
8732 *
8733 * Examples:
8734 * <ul>
8735 * <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 2, 1) -> ["3", "2", "1", "4"]</li>
8736 * <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 0, 1) -> ["1", "2", "3", "4"]</li>
8737 * <li>ArrayUtils.swap(["1", "2", "3", "4"], 2, 0, 2) -> ["3", "4", "1", "2"]</li>
8738 * <li>ArrayUtils.swap(["1", "2", "3", "4"], -3, 2, 2) -> ["3", "4", "1", "2"]</li>
8739 * <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 3, 3) -> ["4", "2", "3", "1"]</li>
8740 * </ul>
8741 *
8742 * @param array the array to swap, may be {@code null}
8743 * @param offset1 the index of the first element in the series to swap
8744 * @param offset2 the index of the second element in the series to swap
8745 * @param len the number of elements to swap starting with the given indices
8746 * @since 3.5
8747 */
8748 public static void swap(final Object[] array, int offset1, int offset2, int len) {
8749 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8750 return;
8751 }
8752 offset1 = max0(offset1);
8753 offset2 = max0(offset2);
8754 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8755 for (int i = 0; i < len; i++, offset1++, offset2++) {
8756 final Object aux = array[offset1];
8757 array[offset1] = array[offset2];
8758 array[offset2] = aux;
8759 }
8760 }
8761
8762 /**
8763 * Swaps two elements in the given short array.
8764 *
8765 * <p>There is no special handling for multi-dimensional arrays. This method
8766 * does nothing for a {@code null} or empty input array or for overflow indices.
8767 * Negative indices are promoted to 0(zero).</p>
8768 *
8769 * Examples:
8770 * <ul>
8771 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8772 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8773 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8774 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8775 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8776 * </ul>
8777 *
8778 * @param array the array to swap, may be {@code null}
8779 * @param offset1 the index of the first element to swap
8780 * @param offset2 the index of the second element to swap
8781 * @since 3.5
8782 */
8783 public static void swap(final short[] array, final int offset1, final int offset2) {
8784 swap(array, offset1, offset2, 1);
8785 }
8786
8787 /**
8788 * Swaps a series of elements in the given short array.
8789 *
8790 * <p>This method does nothing for a {@code null} or empty input array or
8791 * for overflow indices. Negative indices are promoted to 0(zero). If any
8792 * of the sub-arrays to swap falls outside of the given array, then the
8793 * swap is stopped at the end of the array and as many as possible elements
8794 * are swapped.</p>
8795 *
8796 * Examples:
8797 * <ul>
8798 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8799 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8800 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8801 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8802 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8803 * </ul>
8804 *
8805 * @param array the array to swap, may be {@code null}
8806 * @param offset1 the index of the first element in the series to swap
8807 * @param offset2 the index of the second element in the series to swap
8808 * @param len the number of elements to swap starting with the given indices
8809 * @since 3.5
8810 */
8811 public static void swap(final short[] array, int offset1, int offset2, int len) {
8812 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8813 return;
8814 }
8815 offset1 = max0(offset1);
8816 offset2 = max0(offset2);
8817 if (offset1 == offset2) {
8818 return;
8819 }
8820 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8821 for (int i = 0; i < len; i++, offset1++, offset2++) {
8822 final short aux = array[offset1];
8823 array[offset1] = array[offset2];
8824 array[offset2] = aux;
8825 }
8826 }
8827
8828 /**
8829 * Create a type-safe generic array.
8830 * <p>
8831 * The Java language does not allow an array to be created from a generic type:
8832 * </p>
8833 * <pre>
8834 public static <T> T[] createAnArray(int size) {
8835 return new T[size]; // compiler error here
8836 }
8837 public static <T> T[] createAnArray(int size) {
8838 return (T[]) new Object[size]; // ClassCastException at runtime
8839 }
8840 * </pre>
8841 * <p>
8842 * Therefore new arrays of generic types can be created with this method.
8843 * For example, an array of Strings can be created:
8844 * </p>
8845 * <pre>{@code
8846 * String[] array = ArrayUtils.toArray("1", "2");
8847 * String[] emptyArray = ArrayUtils.<String>toArray();
8848 * }</pre>
8849 * <p>
8850 * The method is typically used in scenarios, where the caller itself uses generic types
8851 * that have to be combined into an array.
8852 * </p>
8853 * <p>
8854 * Note, this method makes only sense to provide arguments of the same type so that the
8855 * compiler can deduce the type of the array itself. While it is possible to select the
8856 * type explicitly like in
8857 * {@code Number[] array = ArrayUtils.<Number>toArray(Integer.valueOf(42), Double.valueOf(Math.PI))},
8858 * there is no real advantage when compared to
8859 * {@code new Number[] {Integer.valueOf(42), Double.valueOf(Math.PI)}}.
8860 * </p>
8861 *
8862 * @param <T> the array's element type
8863 * @param items the varargs array items, null allowed
8864 * @return the array, not null unless a null array is passed in
8865 * @since 3.0
8866 */
8867 public static <T> T[] toArray(@SuppressWarnings("unchecked") final T... items) {
8868 return items;
8869 }
8870
8871 /**
8872 * Converts the given array into a {@link java.util.Map}. Each element of the array
8873 * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
8874 * elements, where the first element is used as key and the second as
8875 * value.
8876 * <p>
8877 * This method can be used to initialize:
8878 * </p>
8879 * <pre>
8880 * // Create a Map mapping colors.
8881 * Map colorMap = ArrayUtils.toMap(new String[][] {
8882 * {"RED", "#FF0000"},
8883 * {"GREEN", "#00FF00"},
8884 * {"BLUE", "#0000FF"}});
8885 * </pre>
8886 * <p>
8887 * This method returns {@code null} for a {@code null} input array.
8888 * </p>
8889 *
8890 * @param array an array whose elements are either a {@link java.util.Map.Entry} or
8891 * an Array containing at least two elements, may be {@code null}
8892 * @return a {@link Map} that was created from the array
8893 * @throws IllegalArgumentException if one element of this Array is
8894 * itself an Array containing less than two elements
8895 * @throws IllegalArgumentException if the array contains elements other
8896 * than {@link java.util.Map.Entry} and an Array
8897 */
8898 public static Map<Object, Object> toMap(final Object[] array) {
8899 if (array == null) {
8900 return null;
8901 }
8902 final Map<Object, Object> map = new HashMap<>((int) (array.length * 1.5));
8903 for (int i = 0; i < array.length; i++) {
8904 final Object object = array[i];
8905 if (object instanceof Map.Entry<?, ?>) {
8906 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
8907 map.put(entry.getKey(), entry.getValue());
8908 } else if (object instanceof Object[]) {
8909 final Object[] entry = (Object[]) object;
8910 if (entry.length < 2) {
8911 throw new IllegalArgumentException("Array element " + i + ", '"
8912 + object
8913 + "', has a length less than 2");
8914 }
8915 map.put(entry[0], entry[1]);
8916 } else {
8917 throw new IllegalArgumentException("Array element " + i + ", '"
8918 + object
8919 + "', is neither of type Map.Entry nor an Array");
8920 }
8921 }
8922 return map;
8923 }
8924
8925 /**
8926 * Converts an array of primitive booleans to objects.
8927 *
8928 * <p>This method returns {@code null} for a {@code null} input array.</p>
8929 *
8930 * @param array a {@code boolean} array
8931 * @return a {@link Boolean} array, {@code null} if null array input
8932 */
8933 public static Boolean[] toObject(final boolean[] array) {
8934 if (array == null) {
8935 return null;
8936 }
8937 if (array.length == 0) {
8938 return EMPTY_BOOLEAN_OBJECT_ARRAY;
8939 }
8940 return setAll(new Boolean[array.length], i -> array[i] ? Boolean.TRUE : Boolean.FALSE);
8941 }
8942
8943 /**
8944 * Converts an array of primitive bytes to objects.
8945 *
8946 * <p>This method returns {@code null} for a {@code null} input array.</p>
8947 *
8948 * @param array a {@code byte} array
8949 * @return a {@link Byte} array, {@code null} if null array input
8950 */
8951 public static Byte[] toObject(final byte[] array) {
8952 if (array == null) {
8953 return null;
8954 }
8955 if (array.length == 0) {
8956 return EMPTY_BYTE_OBJECT_ARRAY;
8957 }
8958 return setAll(new Byte[array.length], i -> Byte.valueOf(array[i]));
8959 }
8960
8961 /**
8962 * Converts an array of primitive chars to objects.
8963 *
8964 * <p>This method returns {@code null} for a {@code null} input array.</p>
8965 *
8966 * @param array a {@code char} array
8967 * @return a {@link Character} array, {@code null} if null array input
8968 */
8969 public static Character[] toObject(final char[] array) {
8970 if (array == null) {
8971 return null;
8972 }
8973 if (array.length == 0) {
8974 return EMPTY_CHARACTER_OBJECT_ARRAY;
8975 }
8976 return setAll(new Character[array.length], i -> Character.valueOf(array[i]));
8977 }
8978
8979 /**
8980 * Converts an array of primitive doubles to objects.
8981 *
8982 * <p>This method returns {@code null} for a {@code null} input array.</p>
8983 *
8984 * @param array a {@code double} array
8985 * @return a {@link Double} array, {@code null} if null array input
8986 */
8987 public static Double[] toObject(final double[] array) {
8988 if (array == null) {
8989 return null;
8990 }
8991 if (array.length == 0) {
8992 return EMPTY_DOUBLE_OBJECT_ARRAY;
8993 }
8994 return setAll(new Double[array.length], i -> Double.valueOf(array[i]));
8995 }
8996
8997 /**
8998 * Converts an array of primitive floats to objects.
8999 *
9000 * <p>This method returns {@code null} for a {@code null} input array.</p>
9001 *
9002 * @param array a {@code float} array
9003 * @return a {@link Float} array, {@code null} if null array input
9004 */
9005 public static Float[] toObject(final float[] array) {
9006 if (array == null) {
9007 return null;
9008 }
9009 if (array.length == 0) {
9010 return EMPTY_FLOAT_OBJECT_ARRAY;
9011 }
9012 return setAll(new Float[array.length], i -> Float.valueOf(array[i]));
9013 }
9014
9015 /**
9016 * Converts an array of primitive ints to objects.
9017 *
9018 * <p>This method returns {@code null} for a {@code null} input array.</p>
9019 *
9020 * @param array an {@code int} array
9021 * @return an {@link Integer} array, {@code null} if null array input
9022 */
9023 public static Integer[] toObject(final int[] array) {
9024 if (array == null) {
9025 return null;
9026 }
9027 if (array.length == 0) {
9028 return EMPTY_INTEGER_OBJECT_ARRAY;
9029 }
9030 return setAll(new Integer[array.length], i -> Integer.valueOf(array[i]));
9031 }
9032
9033 /**
9034 * Converts an array of primitive longs to objects.
9035 *
9036 * <p>This method returns {@code null} for a {@code null} input array.</p>
9037 *
9038 * @param array a {@code long} array
9039 * @return a {@link Long} array, {@code null} if null array input
9040 */
9041 public static Long[] toObject(final long[] array) {
9042 if (array == null) {
9043 return null;
9044 }
9045 if (array.length == 0) {
9046 return EMPTY_LONG_OBJECT_ARRAY;
9047 }
9048 return setAll(new Long[array.length], i -> Long.valueOf(array[i]));
9049 }
9050
9051 /**
9052 * Converts an array of primitive shorts to objects.
9053 *
9054 * <p>This method returns {@code null} for a {@code null} input array.</p>
9055 *
9056 * @param array a {@code short} array
9057 * @return a {@link Short} array, {@code null} if null array input
9058 */
9059 public static Short[] toObject(final short[] array) {
9060 if (array == null) {
9061 return null;
9062 }
9063 if (array.length == 0) {
9064 return EMPTY_SHORT_OBJECT_ARRAY;
9065 }
9066 return setAll(new Short[array.length], i -> Short.valueOf(array[i]));
9067 }
9068
9069 /**
9070 * Converts an array of object Booleans to primitives.
9071 * <p>
9072 * This method returns {@code null} for a {@code null} input array.
9073 * </p>
9074 * <p>
9075 * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
9076 * </p>
9077 *
9078 * @param array a {@link Boolean} array, may be {@code null}
9079 * @return a {@code boolean} array, {@code null} if null array input
9080 */
9081 public static boolean[] toPrimitive(final Boolean[] array) {
9082 return toPrimitive(array, false);
9083 }
9084
9085 /**
9086 * Converts an array of object Booleans to primitives handling {@code null}.
9087 * <p>
9088 * This method returns {@code null} for a {@code null} input array.
9089 * </p>
9090 *
9091 * @param array a {@link Boolean} array, may be {@code null}
9092 * @param valueForNull the value to insert if {@code null} found
9093 * @return a {@code boolean} array, {@code null} if null array input
9094 */
9095 public static boolean[] toPrimitive(final Boolean[] array, final boolean valueForNull) {
9096 if (array == null) {
9097 return null;
9098 }
9099 if (array.length == 0) {
9100 return EMPTY_BOOLEAN_ARRAY;
9101 }
9102 final boolean[] result = new boolean[array.length];
9103 for (int i = 0; i < array.length; i++) {
9104 final Boolean b = array[i];
9105 result[i] = b == null ? valueForNull : b.booleanValue();
9106 }
9107 return result;
9108 }
9109
9110 /**
9111 * Converts an array of object Bytes to primitives.
9112 * <p>
9113 * This method returns {@code null} for a {@code null} input array.
9114 * </p>
9115 *
9116 * @param array a {@link Byte} array, may be {@code null}
9117 * @return a {@code byte} array, {@code null} if null array input
9118 * @throws NullPointerException if an array element is {@code null}
9119 */
9120 public static byte[] toPrimitive(final Byte[] array) {
9121 if (array == null) {
9122 return null;
9123 }
9124 if (array.length == 0) {
9125 return EMPTY_BYTE_ARRAY;
9126 }
9127 final byte[] result = new byte[array.length];
9128 for (int i = 0; i < array.length; i++) {
9129 result[i] = array[i].byteValue();
9130 }
9131 return result;
9132 }
9133
9134 /**
9135 * Converts an array of object Bytes to primitives handling {@code null}.
9136 * <p>
9137 * This method returns {@code null} for a {@code null} input array.
9138 * </p>
9139 *
9140 * @param array a {@link Byte} array, may be {@code null}
9141 * @param valueForNull the value to insert if {@code null} found
9142 * @return a {@code byte} array, {@code null} if null array input
9143 */
9144 public static byte[] toPrimitive(final Byte[] array, final byte valueForNull) {
9145 if (array == null) {
9146 return null;
9147 }
9148 if (array.length == 0) {
9149 return EMPTY_BYTE_ARRAY;
9150 }
9151 final byte[] result = new byte[array.length];
9152 for (int i = 0; i < array.length; i++) {
9153 final Byte b = array[i];
9154 result[i] = b == null ? valueForNull : b.byteValue();
9155 }
9156 return result;
9157 }
9158
9159 /**
9160 * Converts an array of object Characters to primitives.
9161 * <p>
9162 * This method returns {@code null} for a {@code null} input array.
9163 * </p>
9164 *
9165 * @param array a {@link Character} array, may be {@code null}
9166 * @return a {@code char} array, {@code null} if null array input
9167 * @throws NullPointerException if an array element is {@code null}
9168 */
9169 public static char[] toPrimitive(final Character[] array) {
9170 if (array == null) {
9171 return null;
9172 }
9173 if (array.length == 0) {
9174 return EMPTY_CHAR_ARRAY;
9175 }
9176 final char[] result = new char[array.length];
9177 for (int i = 0; i < array.length; i++) {
9178 result[i] = array[i].charValue();
9179 }
9180 return result;
9181 }
9182
9183 /**
9184 * Converts an array of object Character to primitives handling {@code null}.
9185 * <p>
9186 * This method returns {@code null} for a {@code null} input array.
9187 * </p>
9188 *
9189 * @param array a {@link Character} array, may be {@code null}
9190 * @param valueForNull the value to insert if {@code null} found
9191 * @return a {@code char} array, {@code null} if null array input
9192 */
9193 public static char[] toPrimitive(final Character[] array, final char valueForNull) {
9194 if (array == null) {
9195 return null;
9196 }
9197 if (array.length == 0) {
9198 return EMPTY_CHAR_ARRAY;
9199 }
9200 final char[] result = new char[array.length];
9201 for (int i = 0; i < array.length; i++) {
9202 final Character b = array[i];
9203 result[i] = b == null ? valueForNull : b.charValue();
9204 }
9205 return result;
9206 }
9207
9208 /**
9209 * Converts an array of object Doubles to primitives.
9210 * <p>
9211 * This method returns {@code null} for a {@code null} input array.
9212 * </p>
9213 *
9214 * @param array a {@link Double} array, may be {@code null}
9215 * @return a {@code double} array, {@code null} if null array input
9216 * @throws NullPointerException if an array element is {@code null}
9217 */
9218 public static double[] toPrimitive(final Double[] array) {
9219 if (array == null) {
9220 return null;
9221 }
9222 if (array.length == 0) {
9223 return EMPTY_DOUBLE_ARRAY;
9224 }
9225 final double[] result = new double[array.length];
9226 for (int i = 0; i < array.length; i++) {
9227 result[i] = array[i].doubleValue();
9228 }
9229 return result;
9230 }
9231
9232 /**
9233 * Converts an array of object Doubles to primitives handling {@code null}.
9234 * <p>
9235 * This method returns {@code null} for a {@code null} input array.
9236 * </p>
9237 *
9238 * @param array a {@link Double} array, may be {@code null}
9239 * @param valueForNull the value to insert if {@code null} found
9240 * @return a {@code double} array, {@code null} if null array input
9241 */
9242 public static double[] toPrimitive(final Double[] array, final double valueForNull) {
9243 if (array == null) {
9244 return null;
9245 }
9246 if (array.length == 0) {
9247 return EMPTY_DOUBLE_ARRAY;
9248 }
9249 final double[] result = new double[array.length];
9250 for (int i = 0; i < array.length; i++) {
9251 final Double b = array[i];
9252 result[i] = b == null ? valueForNull : b.doubleValue();
9253 }
9254 return result;
9255 }
9256
9257 /**
9258 * Converts an array of object Floats to primitives.
9259 * <p>
9260 * This method returns {@code null} for a {@code null} input array.
9261 * </p>
9262 *
9263 * @param array a {@link Float} array, may be {@code null}
9264 * @return a {@code float} array, {@code null} if null array input
9265 * @throws NullPointerException if an array element is {@code null}
9266 */
9267 public static float[] toPrimitive(final Float[] array) {
9268 if (array == null) {
9269 return null;
9270 }
9271 if (array.length == 0) {
9272 return EMPTY_FLOAT_ARRAY;
9273 }
9274 final float[] result = new float[array.length];
9275 for (int i = 0; i < array.length; i++) {
9276 result[i] = array[i].floatValue();
9277 }
9278 return result;
9279 }
9280
9281 /**
9282 * Converts an array of object Floats to primitives handling {@code null}.
9283 * <p>
9284 * This method returns {@code null} for a {@code null} input array.
9285 * </p>
9286 *
9287 * @param array a {@link Float} array, may be {@code null}
9288 * @param valueForNull the value to insert if {@code null} found
9289 * @return a {@code float} array, {@code null} if null array input
9290 */
9291 public static float[] toPrimitive(final Float[] array, final float valueForNull) {
9292 if (array == null) {
9293 return null;
9294 }
9295 if (array.length == 0) {
9296 return EMPTY_FLOAT_ARRAY;
9297 }
9298 final float[] result = new float[array.length];
9299 for (int i = 0; i < array.length; i++) {
9300 final Float b = array[i];
9301 result[i] = b == null ? valueForNull : b.floatValue();
9302 }
9303 return result;
9304 }
9305
9306 /**
9307 * Converts an array of object Integers to primitives.
9308 * <p>
9309 * This method returns {@code null} for a {@code null} input array.
9310 * </p>
9311 *
9312 * @param array a {@link Integer} array, may be {@code null}
9313 * @return an {@code int} array, {@code null} if null array input
9314 * @throws NullPointerException if an array element is {@code null}
9315 */
9316 public static int[] toPrimitive(final Integer[] array) {
9317 if (array == null) {
9318 return null;
9319 }
9320 if (array.length == 0) {
9321 return EMPTY_INT_ARRAY;
9322 }
9323 final int[] result = new int[array.length];
9324 for (int i = 0; i < array.length; i++) {
9325 result[i] = array[i].intValue();
9326 }
9327 return result;
9328 }
9329
9330 /**
9331 * Converts an array of object Integer to primitives handling {@code null}.
9332 * <p>
9333 * This method returns {@code null} for a {@code null} input array.
9334 * </p>
9335 *
9336 * @param array a {@link Integer} array, may be {@code null}
9337 * @param valueForNull the value to insert if {@code null} found
9338 * @return an {@code int} array, {@code null} if null array input
9339 */
9340 public static int[] toPrimitive(final Integer[] array, final int valueForNull) {
9341 if (array == null) {
9342 return null;
9343 }
9344 if (array.length == 0) {
9345 return EMPTY_INT_ARRAY;
9346 }
9347 final int[] result = new int[array.length];
9348 for (int i = 0; i < array.length; i++) {
9349 final Integer b = array[i];
9350 result[i] = b == null ? valueForNull : b.intValue();
9351 }
9352 return result;
9353 }
9354
9355 /**
9356 * Converts an array of object Longs to primitives.
9357 * <p>
9358 * This method returns {@code null} for a {@code null} input array.
9359 * </p>
9360 *
9361 * @param array a {@link Long} array, may be {@code null}
9362 * @return a {@code long} array, {@code null} if null array input
9363 * @throws NullPointerException if an array element is {@code null}
9364 */
9365 public static long[] toPrimitive(final Long[] array) {
9366 if (array == null) {
9367 return null;
9368 }
9369 if (array.length == 0) {
9370 return EMPTY_LONG_ARRAY;
9371 }
9372 final long[] result = new long[array.length];
9373 for (int i = 0; i < array.length; i++) {
9374 result[i] = array[i].longValue();
9375 }
9376 return result;
9377 }
9378
9379 /**
9380 * Converts an array of object Long to primitives handling {@code null}.
9381 * <p>
9382 * This method returns {@code null} for a {@code null} input array.
9383 * </p>
9384 *
9385 * @param array a {@link Long} array, may be {@code null}
9386 * @param valueForNull the value to insert if {@code null} found
9387 * @return a {@code long} array, {@code null} if null array input
9388 */
9389 public static long[] toPrimitive(final Long[] array, final long valueForNull) {
9390 if (array == null) {
9391 return null;
9392 }
9393 if (array.length == 0) {
9394 return EMPTY_LONG_ARRAY;
9395 }
9396 final long[] result = new long[array.length];
9397 for (int i = 0; i < array.length; i++) {
9398 final Long b = array[i];
9399 result[i] = b == null ? valueForNull : b.longValue();
9400 }
9401 return result;
9402 }
9403
9404 /**
9405 * Create an array of primitive type from an array of wrapper types.
9406 * <p>
9407 * This method returns {@code null} for a {@code null} input array.
9408 * </p>
9409 *
9410 * @param array an array of wrapper object
9411 * @return an array of the corresponding primitive type, or the original array
9412 * @since 3.5
9413 */
9414 public static Object toPrimitive(final Object array) {
9415 if (array == null) {
9416 return null;
9417 }
9418 final Class<?> ct = array.getClass().getComponentType();
9419 final Class<?> pt = ClassUtils.wrapperToPrimitive(ct);
9420 if (Boolean.TYPE.equals(pt)) {
9421 return toPrimitive((Boolean[]) array);
9422 }
9423 if (Character.TYPE.equals(pt)) {
9424 return toPrimitive((Character[]) array);
9425 }
9426 if (Byte.TYPE.equals(pt)) {
9427 return toPrimitive((Byte[]) array);
9428 }
9429 if (Integer.TYPE.equals(pt)) {
9430 return toPrimitive((Integer[]) array);
9431 }
9432 if (Long.TYPE.equals(pt)) {
9433 return toPrimitive((Long[]) array);
9434 }
9435 if (Short.TYPE.equals(pt)) {
9436 return toPrimitive((Short[]) array);
9437 }
9438 if (Double.TYPE.equals(pt)) {
9439 return toPrimitive((Double[]) array);
9440 }
9441 if (Float.TYPE.equals(pt)) {
9442 return toPrimitive((Float[]) array);
9443 }
9444 return array;
9445 }
9446
9447 /**
9448 * Converts an array of object Shorts to primitives.
9449 * <p>
9450 * This method returns {@code null} for a {@code null} input array.
9451 * </p>
9452 *
9453 * @param array a {@link Short} array, may be {@code null}
9454 * @return a {@code byte} array, {@code null} if null array input
9455 * @throws NullPointerException if an array element is {@code null}
9456 */
9457 public static short[] toPrimitive(final Short[] array) {
9458 if (array == null) {
9459 return null;
9460 }
9461 if (array.length == 0) {
9462 return EMPTY_SHORT_ARRAY;
9463 }
9464 final short[] result = new short[array.length];
9465 for (int i = 0; i < array.length; i++) {
9466 result[i] = array[i].shortValue();
9467 }
9468 return result;
9469 }
9470
9471 /**
9472 * Converts an array of object Short to primitives handling {@code null}.
9473 * <p>
9474 * This method returns {@code null} for a {@code null} input array.
9475 * </p>
9476 *
9477 * @param array a {@link Short} array, may be {@code null}
9478 * @param valueForNull the value to insert if {@code null} found
9479 * @return a {@code byte} array, {@code null} if null array input
9480 */
9481 public static short[] toPrimitive(final Short[] array, final short valueForNull) {
9482 if (array == null) {
9483 return null;
9484 }
9485 if (array.length == 0) {
9486 return EMPTY_SHORT_ARRAY;
9487 }
9488 final short[] result = new short[array.length];
9489 for (int i = 0; i < array.length; i++) {
9490 final Short b = array[i];
9491 result[i] = b == null ? valueForNull : b.shortValue();
9492 }
9493 return result;
9494 }
9495
9496 /**
9497 * Outputs an array as a String, treating {@code null} as an empty array.
9498 * <p>
9499 * Multi-dimensional arrays are handled correctly, including
9500 * multi-dimensional primitive arrays.
9501 * </p>
9502 * <p>
9503 * The format is that of Java source code, for example {@code {a,b}}.
9504 * </p>
9505 *
9506 * @param array the array to get a toString for, may be {@code null}
9507 * @return a String representation of the array, '{}' if null array input
9508 */
9509 public static String toString(final Object array) {
9510 return toString(array, "{}");
9511 }
9512
9513 /**
9514 * Outputs an array as a String handling {@code null}s.
9515 * <p>
9516 * Multi-dimensional arrays are handled correctly, including
9517 * multi-dimensional primitive arrays.
9518 * </p>
9519 * <p>
9520 * The format is that of Java source code, for example {@code {a,b}}.
9521 * </p>
9522 *
9523 * @param array the array to get a toString for, may be {@code null}
9524 * @param stringIfNull the String to return if the array is {@code null}
9525 * @return a String representation of the array
9526 */
9527 public static String toString(final Object array, final String stringIfNull) {
9528 if (array == null) {
9529 return stringIfNull;
9530 }
9531 return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
9532 }
9533
9534 /**
9535 * Returns an array containing the string representation of each element in the argument array.
9536 * <p>
9537 * This method returns {@code null} for a {@code null} input array.
9538 * </p>
9539 *
9540 * @param array the {@code Object[]} to be processed, may be {@code null}.
9541 * @return {@code String[]} of the same size as the source with its element's string representation,
9542 * {@code null} if null array input
9543 * @since 3.6
9544 */
9545 public static String[] toStringArray(final Object[] array) {
9546 return toStringArray(array, "null");
9547 }
9548
9549 /**
9550 * Returns an array containing the string representation of each element in the argument
9551 * array handling {@code null} elements.
9552 * <p>
9553 * This method returns {@code null} for a {@code null} input array.
9554 * </p>
9555 *
9556 * @param array the Object[] to be processed, may be {@code null}.
9557 * @param valueForNullElements the value to insert if {@code null} is found
9558 * @return a {@link String} array, {@code null} if null array input
9559 * @since 3.6
9560 */
9561 public static String[] toStringArray(final Object[] array, final String valueForNullElements) {
9562 if (null == array) {
9563 return null;
9564 }
9565 if (array.length == 0) {
9566 return EMPTY_STRING_ARRAY;
9567 }
9568 return map(array, String.class, e -> Objects.toString(e, valueForNullElements));
9569 }
9570
9571 /**
9572 * ArrayUtils instances should NOT be constructed in standard programming.
9573 * Instead, the class should be used as {@code ArrayUtils.clone(new int[] {2})}.
9574 * <p>
9575 * This constructor is public to permit tools that require a JavaBean instance
9576 * to operate.
9577 * </p>
9578 *
9579 * @deprecated TODO Make private in 4.0.
9580 */
9581 @Deprecated
9582 public ArrayUtils() {
9583 // empty
9584 }
9585 }