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 *
59 * @since 2.0
60 */
61 public class ArrayUtils {
62
63 /**
64 * Bridge class to {@link Math} methods for testing purposes.
65 */
66 static class MathBridge {
67 static int addExact(final int a, final int b) {
68 return Math.addExact(a, b);
69 }
70 }
71
72 /**
73 * An empty immutable {@code boolean} array.
74 */
75 public static final boolean[] EMPTY_BOOLEAN_ARRAY = {};
76
77 /**
78 * An empty immutable {@link Boolean} array.
79 */
80 public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = {};
81
82 /**
83 * An empty immutable {@code byte} array.
84 */
85 public static final byte[] EMPTY_BYTE_ARRAY = {};
86
87 /**
88 * An empty immutable {@link Byte} array.
89 */
90 public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = {};
91
92 /**
93 * An empty immutable {@code char} array.
94 */
95 public static final char[] EMPTY_CHAR_ARRAY = {};
96
97 /**
98 * An empty immutable {@link Character} array.
99 */
100 public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = {};
101
102 /**
103 * An empty immutable {@link Class} array.
104 */
105 public static final Class<?>[] EMPTY_CLASS_ARRAY = {};
106
107 /**
108 * An empty immutable {@code double} array.
109 */
110 public static final double[] EMPTY_DOUBLE_ARRAY = {};
111
112 /**
113 * An empty immutable {@link Double} array.
114 */
115 public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = {};
116
117 /**
118 * An empty immutable {@link Field} array.
119 *
120 * @since 3.10
121 */
122 public static final Field[] EMPTY_FIELD_ARRAY = {};
123
124 /**
125 * An empty immutable {@code float} array.
126 */
127 public static final float[] EMPTY_FLOAT_ARRAY = {};
128
129 /**
130 * An empty immutable {@link Float} array.
131 */
132 public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = {};
133
134 /**
135 * An empty immutable {@code int} array.
136 */
137 public static final int[] EMPTY_INT_ARRAY = {};
138
139 /**
140 * An empty immutable {@link Integer} array.
141 */
142 public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = {};
143
144 /**
145 * An empty immutable {@code long} array.
146 */
147 public static final long[] EMPTY_LONG_ARRAY = {};
148
149 /**
150 * An empty immutable {@link Long} array.
151 */
152 public static final Long[] EMPTY_LONG_OBJECT_ARRAY = {};
153
154 /**
155 * An empty immutable {@link Method} array.
156 *
157 * @since 3.10
158 */
159 public static final Method[] EMPTY_METHOD_ARRAY = {};
160
161 /**
162 * An empty immutable {@link Object} array.
163 */
164 public static final Object[] EMPTY_OBJECT_ARRAY = {};
165
166 /**
167 * An empty immutable {@code short} array.
168 */
169 public static final short[] EMPTY_SHORT_ARRAY = {};
170
171 /**
172 * An empty immutable {@link Short} array.
173 */
174 public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = {};
175
176 /**
177 * An empty immutable {@link String} array.
178 */
179 public static final String[] EMPTY_STRING_ARRAY = {};
180
181 /**
182 * An empty immutable {@link Throwable} array.
183 *
184 * @since 3.10
185 */
186 public static final Throwable[] EMPTY_THROWABLE_ARRAY = {};
187
188 /**
189 * An empty immutable {@link Type} array.
190 *
191 * @since 3.10
192 */
193 public static final Type[] EMPTY_TYPE_ARRAY = {};
194
195 /**
196 * The index value when an element is not found in a list or array: {@code -1}.
197 * This value is returned by methods in this class and can also be used in comparisons with values returned by
198 * various method from {@link java.util.List}.
199 */
200 public static final int INDEX_NOT_FOUND = -1;
201
202 /**
203 * The {@code SOFT_MAX_ARRAY_LENGTH} constant from Java's internal ArraySupport class.
204 *
205 * @since 3.19.0
206 * @deprecated This variable will be final in 4.0; to guarantee immutability now, use {@link #SAFE_MAX_ARRAY_LENGTH}.
207 */
208 @Deprecated
209 public static int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
210
211 /**
212 * The {@code MAX_ARRAY_LENGTH} constant from Java's internal ArraySupport class.
213 *
214 * @since 3.21.0
215 */
216 public static final int SAFE_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
217
218 /**
219 * Copies the given array and adds the given element at the end of the new array.
220 * <p>
221 * The new array contains the same elements of the input
222 * array plus the given element in the last position. The component type of
223 * the new array is the same as that of the input array.
224 * </p>
225 * <p>
226 * If the input array is {@code null}, a new one element array is returned
227 * whose component type is the same as the element.
228 * </p>
229 * <pre>
230 * ArrayUtils.add(null, true) = [true]
231 * ArrayUtils.add([true], false) = [true, false]
232 * ArrayUtils.add([true, false], true) = [true, false, true]
233 * </pre>
234 *
235 * @param array the array to copy and add the element to, may be {@code null}.
236 * @param element the object to add at the last index of the new array.
237 * @return A new array containing the existing elements plus the new element.
238 * @since 2.1
239 */
240 public static boolean[] add(final boolean[] array, final boolean element) {
241 final boolean[] newArray = (boolean[]) copyArrayGrow1(array, Boolean.TYPE);
242 newArray[newArray.length - 1] = element;
243 return newArray;
244 }
245
246 /**
247 * Inserts the specified element at the specified position in the array.
248 * Shifts the element currently at that position (if any) and any subsequent
249 * elements to the right (adds one to their indices).
250 * <p>
251 * This method returns a new array with the same elements of the input
252 * array plus the given element on the specified position. The component
253 * type of the returned array is always the same as that of the input
254 * array.
255 * </p>
256 * <p>
257 * If the input array is {@code null}, a new one element array is returned
258 * whose component type is the same as the element.
259 * </p>
260 * <pre>
261 * ArrayUtils.add(null, 0, true) = [true]
262 * ArrayUtils.add([true], 0, false) = [false, true]
263 * ArrayUtils.add([false], 1, true) = [false, true]
264 * ArrayUtils.add([true, false], 1, true) = [true, true, false]
265 * </pre>
266 *
267 * @param array the array to add the element to, may be {@code null}.
268 * @param index the position of the new object.
269 * @param element the object to add.
270 * @return A new array containing the existing elements and the new element.
271 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > array.length).
272 * @deprecated this method has been superseded by {@link #insert(int, boolean[], boolean...)} and
273 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
274 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
275 */
276 @Deprecated
277 public static boolean[] add(final boolean[] array, final int index, final boolean element) {
278 return (boolean[]) add(array, index, Boolean.valueOf(element), Boolean.TYPE);
279 }
280
281 /**
282 * Copies the given array and adds the given element at the end of the new array.
283 * <p>
284 * The new array contains the same elements of the input
285 * array plus the given element in the last position. The component type of
286 * the new array is the same as that of the input array.
287 * </p>
288 * <p>
289 * If the input array is {@code null}, a new one element array is returned
290 * whose component type is the same as the element.
291 * </p>
292 * <pre>
293 * ArrayUtils.add(null, 0) = [0]
294 * ArrayUtils.add([1], 0) = [1, 0]
295 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
296 * </pre>
297 *
298 * @param array the array to copy and add the element to, may be {@code null}.
299 * @param element the object to add at the last index of the new array.
300 * @return A new array containing the existing elements plus the new element.
301 * @since 2.1
302 */
303 public static byte[] add(final byte[] array, final byte element) {
304 final byte[] newArray = (byte[]) copyArrayGrow1(array, Byte.TYPE);
305 newArray[newArray.length - 1] = element;
306 return newArray;
307 }
308
309 /**
310 * Inserts the specified element at the specified position in the array.
311 * Shifts the element currently at that position (if any) and any subsequent
312 * elements to the right (adds one to their indices).
313 * <p>
314 * This method returns a new array with the same elements of the input
315 * array plus the given element on the specified position. The component
316 * type of the returned array is always the same as that of the input
317 * array.
318 * </p>
319 * <p>
320 * If the input array is {@code null}, a new one element array is returned
321 * whose component type is the same as the element.
322 * </p>
323 * <pre>
324 * ArrayUtils.add([1], 0, 2) = [2, 1]
325 * ArrayUtils.add([2, 6], 2, 3) = [2, 6, 3]
326 * ArrayUtils.add([2, 6], 0, 1) = [1, 2, 6]
327 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
328 * </pre>
329 *
330 * @param array the array to add the element to, may be {@code null}.
331 * @param index the position of the new object.
332 * @param element the object to add.
333 * @return A new array containing the existing elements and the new element.
334 * @throws IndexOutOfBoundsException if the index is out of range.
335 * (index < 0 || index > array.length).
336 * @deprecated this method has been superseded by {@link #insert(int, byte[], byte...)} and
337 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
338 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
339 */
340 @Deprecated
341 public static byte[] add(final byte[] array, final int index, final byte element) {
342 return (byte[]) add(array, index, Byte.valueOf(element), Byte.TYPE);
343 }
344
345 /**
346 * Copies the given array and adds the given element at the end of the new array.
347 * <p>
348 * The new array contains the same elements of the input
349 * array plus the given element in the last position. The component type of
350 * the new array is the same as that of the input array.
351 * </p>
352 * <p>
353 * If the input array is {@code null}, a new one element array is returned
354 * whose component type is the same as the element.
355 * </p>
356 * <pre>
357 * ArrayUtils.add(null, '0') = ['0']
358 * ArrayUtils.add(['1'], '0') = ['1', '0']
359 * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
360 * </pre>
361 *
362 * @param array the array to copy and add the element to, may be {@code null}.
363 * @param element the object to add at the last index of the new array.
364 * @return A new array containing the existing elements plus the new element.
365 * @since 2.1
366 */
367 public static char[] add(final char[] array, final char element) {
368 final char[] newArray = (char[]) copyArrayGrow1(array, Character.TYPE);
369 newArray[newArray.length - 1] = element;
370 return newArray;
371 }
372
373 /**
374 * Inserts the specified element at the specified position in the array.
375 * Shifts the element currently at that position (if any) and any subsequent
376 * elements to the right (adds one to their indices).
377 * <p>
378 * This method returns a new array with the same elements of the input
379 * array plus the given element on the specified position. The component
380 * type of the returned array is always the same as that of the input
381 * array.
382 * </p>
383 * <p>
384 * If the input array is {@code null}, a new one element array is returned
385 * whose component type is the same as the element.
386 * </p>
387 * <pre>
388 * ArrayUtils.add(null, 0, 'a') = ['a']
389 * ArrayUtils.add(['a'], 0, 'b') = ['b', 'a']
390 * ArrayUtils.add(['a', 'b'], 0, 'c') = ['c', 'a', 'b']
391 * ArrayUtils.add(['a', 'b'], 1, 'k') = ['a', 'k', 'b']
392 * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
393 * </pre>
394 *
395 * @param array the array to add the element to, may be {@code null}.
396 * @param index the position of the new object.
397 * @param element the object to add.
398 * @return A new array containing the existing elements and the new element.
399 * @throws IndexOutOfBoundsException if the index is out of range.
400 * (index < 0 || index > array.length).
401 * @deprecated this method has been superseded by {@link #insert(int, char[], char...)} and
402 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
403 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
404 */
405 @Deprecated
406 public static char[] add(final char[] array, final int index, final char element) {
407 return (char[]) add(array, index, Character.valueOf(element), Character.TYPE);
408 }
409
410 /**
411 * Copies the given array and adds the given element at the end of the new array.
412 *
413 * <p>
414 * The new array contains the same elements of the input
415 * array plus the given element in the last position. The component type of
416 * the new array is the same as that of the input array.
417 * </p>
418 * <p>
419 * If the input array is {@code null}, a new one element array is returned
420 * whose component type is the same as the element.
421 * </p>
422 * <pre>
423 * ArrayUtils.add(null, 0) = [0]
424 * ArrayUtils.add([1], 0) = [1, 0]
425 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
426 * </pre>
427 *
428 * @param array the array to copy and add the element to, may be {@code null}.
429 * @param element the object to add at the last index of the new array.
430 * @return A new array containing the existing elements plus the new element.
431 * @since 2.1
432 */
433 public static double[] add(final double[] array, final double element) {
434 final double[] newArray = (double[]) copyArrayGrow1(array, Double.TYPE);
435 newArray[newArray.length - 1] = element;
436 return newArray;
437 }
438
439 /**
440 * Inserts the specified element at the specified position in the array.
441 * Shifts the element currently at that position (if any) and any subsequent
442 * elements to the right (adds one to their indices).
443 * <p>
444 * This method returns a new array with the same elements of the input
445 * array plus the given element on the specified position. The component
446 * type of the returned array is always the same as that of the input
447 * array.
448 * </p>
449 * <p>
450 * If the input array is {@code null}, a new one element array is returned
451 * whose component type is the same as the element.
452 * </p>
453 * <pre>
454 * ArrayUtils.add([1.1], 0, 2.2) = [2.2, 1.1]
455 * ArrayUtils.add([2.3, 6.4], 2, 10.5) = [2.3, 6.4, 10.5]
456 * ArrayUtils.add([2.6, 6.7], 0, -4.8) = [-4.8, 2.6, 6.7]
457 * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0) = [2.9, 6.0, 1.0, 0.3]
458 * </pre>
459 *
460 * @param array the array to add the element to, may be {@code null}.
461 * @param index the position of the new object.
462 * @param element the object to add.
463 * @return A new array containing the existing elements and the new element.
464 * @throws IndexOutOfBoundsException if the index is out of range
465 * (index < 0 || index > array.length).
466 * @deprecated this method has been superseded by {@link #insert(int, double[], double...)} and
467 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
468 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
469 */
470 @Deprecated
471 public static double[] add(final double[] array, final int index, final double element) {
472 return (double[]) add(array, index, Double.valueOf(element), Double.TYPE);
473 }
474
475 /**
476 * Copies the given array and adds the given element at the end of the new array.
477 * <p>
478 * The new array contains the same elements of the input
479 * array plus the given element in the last position. The component type of
480 * the new array is the same as that of the input array.
481 * </p>
482 * <p>
483 * If the input array is {@code null}, a new one element array is returned
484 * whose component type is the same as the element.
485 * </p>
486 * <pre>
487 * ArrayUtils.add(null, 0) = [0]
488 * ArrayUtils.add([1], 0) = [1, 0]
489 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
490 * </pre>
491 *
492 * @param array the array to copy and add the element to, may be {@code null}.
493 * @param element the object to add at the last index of the new array.
494 * @return A new array containing the existing elements plus the new element.
495 * @since 2.1
496 */
497 public static float[] add(final float[] array, final float element) {
498 final float[] newArray = (float[]) copyArrayGrow1(array, Float.TYPE);
499 newArray[newArray.length - 1] = element;
500 return newArray;
501 }
502
503 /**
504 * Inserts the specified element at the specified position in the array.
505 * Shifts the element currently at that position (if any) and any subsequent
506 * elements to the right (adds one to their indices).
507 * <p>
508 * This method returns a new array with the same elements of the input
509 * array plus the given element on the specified position. The component
510 * type of the returned array is always the same as that of the input
511 * array.
512 * </p>
513 * <p>
514 * If the input array is {@code null}, a new one element array is returned
515 * whose component type is the same as the element.
516 * </p>
517 * <pre>
518 * ArrayUtils.add([1.1f], 0, 2.2f) = [2.2f, 1.1f]
519 * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f) = [2.3f, 6.4f, 10.5f]
520 * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f) = [-4.8f, 2.6f, 6.7f]
521 * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f) = [2.9f, 6.0f, 1.0f, 0.3f]
522 * </pre>
523 *
524 * @param array the array to add the element to, may be {@code null}.
525 * @param index the position of the new object.
526 * @param element the object to add.
527 * @return A new array containing the existing elements and the new element.
528 * @throws IndexOutOfBoundsException if the index is out of range
529 * (index < 0 || index > array.length).
530 * @deprecated this method has been superseded by {@link #insert(int, float[], float...)} and
531 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
532 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
533 */
534 @Deprecated
535 public static float[] add(final float[] array, final int index, final float element) {
536 return (float[]) add(array, index, Float.valueOf(element), Float.TYPE);
537 }
538
539 /**
540 * Copies the given array and adds the given element at the end of the new array.
541 * <p>
542 * The new array contains the same elements of the input
543 * array plus the given element in the last position. The component type of
544 * the new array is the same as that of the input array.
545 * </p>
546 * <p>
547 * If the input array is {@code null}, a new one element array is returned
548 * whose component type is the same as the element.
549 * </p>
550 * <pre>
551 * ArrayUtils.add(null, 0) = [0]
552 * ArrayUtils.add([1], 0) = [1, 0]
553 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
554 * </pre>
555 *
556 * @param array the array to copy and add the element to, may be {@code null}.
557 * @param element the object to add at the last index of the new array.
558 * @return A new array containing the existing elements plus the new element.
559 * @since 2.1
560 */
561 public static int[] add(final int[] array, final int element) {
562 final int[] newArray = (int[]) copyArrayGrow1(array, Integer.TYPE);
563 newArray[newArray.length - 1] = element;
564 return newArray;
565 }
566
567 /**
568 * Inserts the specified element at the specified position in the array.
569 * Shifts the element currently at that position (if any) and any subsequent
570 * elements to the right (adds one to their indices).
571 * <p>
572 * This method returns a new array with the same elements of the input
573 * array plus the given element on the specified position. The component
574 * type of the returned array is always the same as that of the input
575 * array.
576 * </p>
577 * <p>
578 * If the input array is {@code null}, a new one element array is returned
579 * whose component type is the same as the element.
580 * </p>
581 * <pre>
582 * ArrayUtils.add([1], 0, 2) = [2, 1]
583 * ArrayUtils.add([2, 6], 2, 10) = [2, 6, 10]
584 * ArrayUtils.add([2, 6], 0, -4) = [-4, 2, 6]
585 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
586 * </pre>
587 *
588 * @param array the array to add the element to, may be {@code null}.
589 * @param index the position of the new object.
590 * @param element the object to add.
591 * @return A new array containing the existing elements and the new element.
592 * @throws IndexOutOfBoundsException if the index is out of range
593 * (index < 0 || index > array.length).
594 * @deprecated this method has been superseded by {@link #insert(int, int[], int...)} and
595 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
596 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
597 */
598 @Deprecated
599 public static int[] add(final int[] array, final int index, final int element) {
600 return (int[]) add(array, index, Integer.valueOf(element), Integer.TYPE);
601 }
602
603 /**
604 * Inserts the specified element at the specified position in the array.
605 * Shifts the element currently at that position (if any) and any subsequent
606 * elements to the right (adds one to their indices).
607 * <p>
608 * This method returns a new array with the same elements of the input
609 * array plus the given element on the specified position. The component
610 * type of the returned array is always the same as that of the input
611 * array.
612 * </p>
613 * <p>
614 * If the input array is {@code null}, a new one element array is returned
615 * whose component type is the same as the element.
616 * </p>
617 * <pre>
618 * ArrayUtils.add([1L], 0, 2L) = [2L, 1L]
619 * ArrayUtils.add([2L, 6L], 2, 10L) = [2L, 6L, 10L]
620 * ArrayUtils.add([2L, 6L], 0, -4L) = [-4L, 2L, 6L]
621 * ArrayUtils.add([2L, 6L, 3L], 2, 1L) = [2L, 6L, 1L, 3L]
622 * </pre>
623 *
624 * @param array the array to add the element to, may be {@code null}.
625 * @param index the position of the new object.
626 * @param element the object to add.
627 * @return A new array containing the existing elements and the new element.
628 * @throws IndexOutOfBoundsException if the index is out of range
629 * (index < 0 || index > array.length).
630 * @deprecated this method has been superseded by {@link #insert(int, long[], long...)} and
631 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
632 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
633 */
634 @Deprecated
635 public static long[] add(final long[] array, final int index, final long element) {
636 return (long[]) add(array, index, Long.valueOf(element), Long.TYPE);
637 }
638
639 /**
640 * Copies the given array and adds the given element at the end of the new array.
641 * <p>
642 * The new array contains the same elements of the input
643 * array plus the given element in the last position. The component type of
644 * the new array is the same as that of the input array.
645 * </p>
646 * <p>
647 * If the input array is {@code null}, a new one element array is returned
648 * whose component type is the same as the element.
649 * </p>
650 * <pre>
651 * ArrayUtils.add(null, 0) = [0]
652 * ArrayUtils.add([1], 0) = [1, 0]
653 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
654 * </pre>
655 *
656 * @param array the array to copy and add the element to, may be {@code null}.
657 * @param element the object to add at the last index of the new array.
658 * @return A new array containing the existing elements plus the new element.
659 * @since 2.1
660 */
661 public static long[] add(final long[] array, final long element) {
662 final long[] newArray = (long[]) copyArrayGrow1(array, Long.TYPE);
663 newArray[newArray.length - 1] = element;
664 return newArray;
665 }
666
667 /**
668 * Underlying implementation of add(array, index, element) methods.
669 * The last parameter is the class, which may not equal element.getClass
670 * for primitives.
671 *
672 * @param array the array to add the element to, may be {@code null}.
673 * @param index the position of the new object.
674 * @param element the object to add.
675 * @param clazz the type of the element being added.
676 * @return A new array containing the existing elements and the new element.
677 */
678 private static Object add(final Object array, final int index, final Object element, final Class<?> clazz) {
679 if (array == null) {
680 if (index != 0) {
681 throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
682 }
683 final Object joinedArray = Array.newInstance(clazz, 1);
684 Array.set(joinedArray, 0, element);
685 return joinedArray;
686 }
687 final int length = Array.getLength(array);
688 if (index > length || index < 0) {
689 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
690 }
691 final Object result = arraycopy(array, 0, 0, index, () -> Array.newInstance(clazz, length + 1));
692 Array.set(result, index, element);
693 if (index < length) {
694 System.arraycopy(array, index, result, index + 1, length - index);
695 }
696 return result;
697 }
698
699 /**
700 * Inserts the specified element at the specified position in the array.
701 * Shifts the element currently at that position (if any) and any subsequent
702 * elements to the right (adds one to their indices).
703 * <p>
704 * This method returns a new array with the same elements of the input
705 * array plus the given element on the specified position. The component
706 * type of the returned array is always the same as that of the input
707 * array.
708 * </p>
709 * <p>
710 * If the input array is {@code null}, a new one element array is returned
711 * whose component type is the same as the element.
712 * </p>
713 * <pre>
714 * ArrayUtils.add([1], 0, 2) = [2, 1]
715 * ArrayUtils.add([2, 6], 2, 10) = [2, 6, 10]
716 * ArrayUtils.add([2, 6], 0, -4) = [-4, 2, 6]
717 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
718 * </pre>
719 *
720 * @param array the array to add the element to, may be {@code null}.
721 * @param index the position of the new object.
722 * @param element the object to add.
723 * @return A new array containing the existing elements and the new element.
724 * @throws IndexOutOfBoundsException if the index is out of range
725 * (index < 0 || index > array.length).
726 * @deprecated this method has been superseded by {@link #insert(int, short[], short...)} and
727 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
728 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
729 */
730 @Deprecated
731 public static short[] add(final short[] array, final int index, final short element) {
732 return (short[]) add(array, index, Short.valueOf(element), Short.TYPE);
733 }
734
735 /**
736 * Copies the given array and adds the given element at the end of the new array.
737 * <p>
738 * The new array contains the same elements of the input
739 * array plus the given element in the last position. The component type of
740 * the new array is the same as that of the input array.
741 * </p>
742 * <p>
743 * If the input array is {@code null}, a new one element array is returned
744 * whose component type is the same as the element.
745 * </p>
746 * <pre>
747 * ArrayUtils.add(null, 0) = [0]
748 * ArrayUtils.add([1], 0) = [1, 0]
749 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
750 * </pre>
751 *
752 * @param array the array to copy and add the element to, may be {@code null}.
753 * @param element the object to add at the last index of the new array.
754 * @return A new array containing the existing elements plus the new element.
755 * @since 2.1
756 */
757 public static short[] add(final short[] array, final short element) {
758 final short[] newArray = (short[]) copyArrayGrow1(array, Short.TYPE);
759 newArray[newArray.length - 1] = element;
760 return newArray;
761 }
762
763 /**
764 * Inserts the specified element at the specified position in the array.
765 * Shifts the element currently at that position (if any) and any subsequent
766 * elements to the right (adds one to their indices).
767 * <p>
768 * This method returns a new array with the same elements of the input
769 * array plus the given element on the specified position. The component
770 * type of the returned array is always the same as that of the input
771 * array.
772 * </p>
773 * <p>
774 * If the input array is {@code null}, a new one element array is returned
775 * whose component type is the same as the element.
776 * </p>
777 * <pre>
778 * ArrayUtils.add(null, 0, null) = Throws {@link IllegalArgumentException}
779 * ArrayUtils.add(null, 0, "a") = ["a"]
780 * ArrayUtils.add(["a"], 1, null) = ["a", null]
781 * ArrayUtils.add(["a"], 1, "b") = ["a", "b"]
782 * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
783 * </pre>
784 *
785 * @param <T> the component type of the array.
786 * @param array the array to add the element to, may be {@code null}.
787 * @param index the position of the new object.
788 * @param element the object to add.
789 * @return A new array containing the existing elements and the new element.
790 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > array.length).
791 * @throws IllegalArgumentException if both array and element are null.
792 * @deprecated this method has been superseded by {@link #insert(int, Object[], Object...) insert(int, T[], T...)} and
793 * may be removed in a future release. Please note the handling of {@code null} input arrays differs
794 * in the new method: inserting {@code X} into a {@code null} array results in {@code null} not {@code X}.
795 */
796 @Deprecated
797 public static <T> T[] add(final T[] array, final int index, final T element) {
798 final Class<T> clazz;
799 if (array != null) {
800 clazz = getComponentType(array);
801 } else if (element != null) {
802 clazz = ObjectUtils.getClass(element);
803 } else {
804 throw new IllegalArgumentException("Array and element cannot both be null");
805 }
806 return (T[]) add(array, index, element, clazz);
807 }
808
809 /**
810 * Copies the given array and adds the given element at the end of the new array.
811 * <p>
812 * The new array contains the same elements of the input
813 * array plus the given element in the last position. The component type of
814 * the new array is the same as that of the input array.
815 * </p>
816 * <p>
817 * If the input array is {@code null}, a new one element array is returned
818 * whose component type is the same as the element, unless the element itself is null,
819 * in which case the return type is Object[]
820 * </p>
821 * <pre>
822 * ArrayUtils.add(null, null) = Throws {@link IllegalArgumentException}
823 * ArrayUtils.add(null, "a") = ["a"]
824 * ArrayUtils.add(["a"], null) = ["a", null]
825 * ArrayUtils.add(["a"], "b") = ["a", "b"]
826 * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
827 * </pre>
828 *
829 * @param <T> the component type of the array.
830 * @param array the array to "add" the element to, may be {@code null}.
831 * @param element the object to add, may be {@code null}.
832 * @return A new array containing the existing elements plus the new element
833 * The returned array type will be that of the input array (unless null),
834 * in which case it will have the same type as the element.
835 * If both are null, an IllegalArgumentException is thrown.
836 * @throws IllegalArgumentException if both arguments are null.
837 * @since 2.1
838 */
839 public static <T> T[] add(final T[] array, final T element) {
840 final Class<?> type;
841 if (array != null) {
842 type = array.getClass().getComponentType();
843 } else if (element != null) {
844 type = element.getClass();
845 } else {
846 throw new IllegalArgumentException("Arguments cannot both be null");
847 }
848 @SuppressWarnings("unchecked") // type must be T
849 final
850 T[] newArray = (T[]) copyArrayGrow1(array, type);
851 newArray[newArray.length - 1] = element;
852 return newArray;
853 }
854
855 /**
856 * Adds all the elements of the given arrays into a new array.
857 * <p>
858 * The new array contains all of the element of {@code array1} followed
859 * by all of the elements {@code array2}. When an array is returned, it is always
860 * a new array.
861 * </p>
862 * <pre>
863 * ArrayUtils.addAll(array1, null) = cloned copy of array1
864 * ArrayUtils.addAll(null, array2) = cloned copy of array2
865 * ArrayUtils.addAll([], []) = []
866 * ArrayUtils.addAll(null, null) = null
867 * </pre>
868 *
869 * @param array1 the first array whose elements are added to the new array.
870 * @param array2 the second array whose elements are added to the new array.
871 * @return The new boolean[] array or {@code null}.
872 * @since 2.1
873 */
874 public static boolean[] addAll(final boolean[] array1, final boolean... array2) {
875 if (array1 == null) {
876 return clone(array2);
877 }
878 if (array2 == null) {
879 return clone(array1);
880 }
881 final boolean[] joinedArray = new boolean[array1.length + array2.length];
882 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
883 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
884 return joinedArray;
885 }
886
887 /**
888 * Adds all the elements of the given arrays into a new array.
889 * <p>
890 * The new array contains all of the element of {@code array1} followed
891 * by all of the elements {@code array2}. When an array is returned, it is always
892 * a new array.
893 * </p>
894 * <pre>
895 * ArrayUtils.addAll(array1, null) = cloned copy of array1
896 * ArrayUtils.addAll(null, array2) = cloned copy of array2
897 * ArrayUtils.addAll([], []) = []
898 * ArrayUtils.addAll(null, null) = null
899 * </pre>
900 *
901 * @param array1 the first array whose elements are added to the new array.
902 * @param array2 the second array whose elements are added to the new array.
903 * @return The new byte[] array or {@code null}.
904 * @since 2.1
905 */
906 public static byte[] addAll(final byte[] array1, final byte... array2) {
907 if (array1 == null) {
908 return clone(array2);
909 }
910 if (array2 == null) {
911 return clone(array1);
912 }
913 final byte[] joinedArray = new byte[array1.length + array2.length];
914 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
915 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
916 return joinedArray;
917 }
918
919 /**
920 * Adds all the elements of the given arrays into a new array.
921 * <p>
922 * The new array contains all of the element of {@code array1} followed
923 * by all of the elements {@code array2}. When an array is returned, it is always
924 * a new array.
925 * </p>
926 * <pre>
927 * ArrayUtils.addAll(array1, null) = cloned copy of array1
928 * ArrayUtils.addAll(null, array2) = cloned copy of array2
929 * ArrayUtils.addAll([], []) = []
930 * ArrayUtils.addAll(null, null) = null
931 * </pre>
932 *
933 * @param array1 the first array whose elements are added to the new array.
934 * @param array2 the second array whose elements are added to the new array.
935 * @return The new char[] array or {@code null}.
936 * @since 2.1
937 */
938 public static char[] addAll(final char[] array1, final char... array2) {
939 if (array1 == null) {
940 return clone(array2);
941 }
942 if (array2 == null) {
943 return clone(array1);
944 }
945 final char[] joinedArray = new char[array1.length + array2.length];
946 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
947 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
948 return joinedArray;
949 }
950
951 /**
952 * Adds all the elements of the given arrays into a new array.
953 * <p>
954 * The new array contains all of the element of {@code array1} followed
955 * by all of the elements {@code array2}. When an array is returned, it is always
956 * a new array.
957 * </p>
958 * <pre>
959 * ArrayUtils.addAll(array1, null) = cloned copy of array1
960 * ArrayUtils.addAll(null, array2) = cloned copy of array2
961 * ArrayUtils.addAll([], []) = []
962 * ArrayUtils.addAll(null, null) = null
963 * </pre>
964 *
965 * @param array1 the first array whose elements are added to the new array.
966 * @param array2 the second array whose elements are added to the new array.
967 * @return The new double[] array or {@code null}.
968 * @since 2.1
969 */
970 public static double[] addAll(final double[] array1, final double... array2) {
971 if (array1 == null) {
972 return clone(array2);
973 }
974 if (array2 == null) {
975 return clone(array1);
976 }
977 final double[] joinedArray = new double[array1.length + array2.length];
978 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
979 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
980 return joinedArray;
981 }
982
983 /**
984 * Adds all the elements of the given arrays into a new array.
985 * <p>
986 * The new array contains all of the element of {@code array1} followed
987 * by all of the elements {@code array2}. When an array is returned, it is always
988 * a new array.
989 * </p>
990 * <pre>
991 * ArrayUtils.addAll(array1, null) = cloned copy of array1
992 * ArrayUtils.addAll(null, array2) = cloned copy of array2
993 * ArrayUtils.addAll([], []) = []
994 * ArrayUtils.addAll(null, null) = null
995 * </pre>
996 *
997 * @param array1 the first array whose elements are added to the new array.
998 * @param array2 the second array whose elements are added to the new array.
999 * @return The new float[] array or {@code null}.
1000 * @since 2.1
1001 */
1002 public static float[] addAll(final float[] array1, final float... array2) {
1003 if (array1 == null) {
1004 return clone(array2);
1005 }
1006 if (array2 == null) {
1007 return clone(array1);
1008 }
1009 final float[] joinedArray = new float[array1.length + array2.length];
1010 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
1011 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1012 return joinedArray;
1013 }
1014
1015 /**
1016 * Adds all the elements of the given arrays into a new array.
1017 * <p>
1018 * The new array contains all of the element of {@code array1} followed
1019 * by all of the elements {@code array2}. When an array is returned, it is always
1020 * a new array.
1021 * </p>
1022 * <pre>
1023 * ArrayUtils.addAll(array1, null) = cloned copy of array1
1024 * ArrayUtils.addAll(null, array2) = cloned copy of array2
1025 * ArrayUtils.addAll([], []) = []
1026 * ArrayUtils.addAll(null, null) = null
1027 * </pre>
1028 *
1029 * @param array1 the first array whose elements are added to the new array.
1030 * @param array2 the second array whose elements are added to the new array.
1031 * @return The new int[] array or {@code null}.
1032 * @since 2.1
1033 */
1034 public static int[] addAll(final int[] array1, final int... array2) {
1035 if (array1 == null) {
1036 return clone(array2);
1037 }
1038 if (array2 == null) {
1039 return clone(array1);
1040 }
1041 final int[] joinedArray = new int[array1.length + array2.length];
1042 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
1043 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1044 return joinedArray;
1045 }
1046
1047 /**
1048 * Adds all the elements of the given arrays into a new array.
1049 * <p>
1050 * The new array contains all of the element of {@code array1} followed
1051 * by all of the elements {@code array2}. When an array is returned, it is always
1052 * a new array.
1053 * </p>
1054 * <pre>
1055 * ArrayUtils.addAll(array1, null) = cloned copy of array1
1056 * ArrayUtils.addAll(null, array2) = cloned copy of array2
1057 * ArrayUtils.addAll([], []) = []
1058 * ArrayUtils.addAll(null, null) = null
1059 * </pre>
1060 *
1061 * @param array1 the first array whose elements are added to the new array.
1062 * @param array2 the second array whose elements are added to the new array.
1063 * @return The new long[] array or {@code null}.
1064 * @since 2.1
1065 */
1066 public static long[] addAll(final long[] array1, final long... array2) {
1067 if (array1 == null) {
1068 return clone(array2);
1069 }
1070 if (array2 == null) {
1071 return clone(array1);
1072 }
1073 final long[] joinedArray = new long[array1.length + array2.length];
1074 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
1075 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1076 return joinedArray;
1077 }
1078
1079 /**
1080 * Adds all the elements of the given arrays into a new array.
1081 * <p>
1082 * The new array contains all of the element of {@code array1} followed
1083 * by all of the elements {@code array2}. When an array is returned, it is always
1084 * a new array.
1085 * </p>
1086 * <pre>
1087 * ArrayUtils.addAll(array1, null) = cloned copy of array1
1088 * ArrayUtils.addAll(null, array2) = cloned copy of array2
1089 * ArrayUtils.addAll([], []) = []
1090 * ArrayUtils.addAll(null, null) = null
1091 * </pre>
1092 *
1093 * @param array1 the first array whose elements are added to the new array.
1094 * @param array2 the second array whose elements are added to the new array.
1095 * @return The new short[] array or {@code null}.
1096 * @since 2.1
1097 */
1098 public static short[] addAll(final short[] array1, final short... array2) {
1099 if (array1 == null) {
1100 return clone(array2);
1101 }
1102 if (array2 == null) {
1103 return clone(array1);
1104 }
1105 final short[] joinedArray = new short[array1.length + array2.length];
1106 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
1107 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1108 return joinedArray;
1109 }
1110
1111 /**
1112 * Adds all the elements of the given arrays into a new array.
1113 * <p>
1114 * The new array contains all of the element of {@code array1} followed
1115 * by all of the elements {@code array2}. When an array is returned, it is always
1116 * a new array.
1117 * </p>
1118 * <pre>
1119 * ArrayUtils.addAll(null, null) = null
1120 * ArrayUtils.addAll(array1, null) = cloned copy of array1
1121 * ArrayUtils.addAll(null, array2) = cloned copy of array2
1122 * ArrayUtils.addAll([], []) = []
1123 * ArrayUtils.addAll(null, null) = null
1124 * ArrayUtils.addAll([null], [null]) = [null, null]
1125 * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
1126 * </pre>
1127 *
1128 * @param <T> the component type of the array.
1129 * @param array1 the first array whose elements are added to the new array, may be {@code null}.
1130 * @param array2 the second array whose elements are added to the new array, may be {@code null}.
1131 * @return The new array, {@code null} if both arrays are {@code null}.
1132 * The type of the new array is the type of the first array,
1133 * unless the first array is null, in which case the type is the same as the second array.
1134 * @throws IllegalArgumentException if the array types are incompatible.
1135 * @since 2.1
1136 */
1137 public static <T> T[] addAll(final T[] array1, @SuppressWarnings("unchecked") final T... array2) {
1138 if (array1 == null) {
1139 return clone(array2);
1140 }
1141 if (array2 == null) {
1142 return clone(array1);
1143 }
1144 final Class<T> type1 = getComponentType(array1);
1145 final T[] joinedArray = arraycopy(array1, 0, 0, array1.length, () -> newInstance(type1, array1.length + array2.length));
1146 try {
1147 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
1148 } catch (final ArrayStoreException ase) {
1149 // Check if problem was due to incompatible types
1150 /*
1151 * 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
1152 * strict
1153 */
1154 final Class<?> type2 = array2.getClass().getComponentType();
1155 if (!type1.isAssignableFrom(type2)) {
1156 throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of " + type1.getName(), ase);
1157 }
1158 throw ase; // No, so rethrow original
1159 }
1160 return joinedArray;
1161 }
1162
1163 /**
1164 * Safely adds the length of an array to a running total, checking for overflow.
1165 *
1166 * @param totalLength the current accumulated length
1167 * @param array the array whose length should be added (can be {@code null},
1168 * in which case its length is considered 0)
1169 * @return the new total length after adding the array's length
1170 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1171 */
1172 private static int addExact(final int totalLength, final Object array) {
1173 try {
1174 final int length = MathBridge.addExact(totalLength, getLength(array));
1175 if (length > SAFE_MAX_ARRAY_LENGTH) {
1176 throw new IllegalArgumentException("Total arrays length exceed " + SAFE_MAX_ARRAY_LENGTH);
1177 }
1178 return length;
1179 } catch (final ArithmeticException exception) {
1180 throw new IllegalArgumentException("Total arrays length exceed " + SAFE_MAX_ARRAY_LENGTH);
1181 }
1182 }
1183
1184 /**
1185 * Copies the given array and adds the given element at the beginning of the new array.
1186 * <p>
1187 * The new array contains the same elements of the input array plus the given element in the first position. The
1188 * component type of the new array is the same as that of the input array.
1189 * </p>
1190 * <p>
1191 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1192 * element.
1193 * </p>
1194 * <pre>
1195 * ArrayUtils.addFirst(null, true) = [true]
1196 * ArrayUtils.addFirst([true], false) = [false, true]
1197 * ArrayUtils.addFirst([true, false], true) = [true, true, false]
1198 * </pre>
1199 *
1200 * @param array the array to "add" the element to, may be {@code null}.
1201 * @param element the object to add.
1202 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1203 * the input array (unless null), in which case it will have the same type as the element.
1204 * @since 3.10
1205 */
1206 public static boolean[] addFirst(final boolean[] array, final boolean element) {
1207 return array == null ? add(array, element) : insert(0, array, element);
1208 }
1209
1210 /**
1211 * Copies the given array and adds the given element at the beginning of the new array.
1212 * <p>
1213 * The new array contains the same elements of the input array plus the given element in the first position. The
1214 * component type of the new array is the same as that of the input array.
1215 * </p>
1216 * <p>
1217 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1218 * element.
1219 * </p>
1220 * <pre>
1221 * ArrayUtils.addFirst(null, 1) = [1]
1222 * ArrayUtils.addFirst([1], 0) = [0, 1]
1223 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1224 * </pre>
1225 *
1226 * @param array the array to "add" the element to, may be {@code null}.
1227 * @param element the object to add.
1228 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1229 * the input array (unless null), in which case it will have the same type as the element.
1230 * @since 3.10
1231 */
1232 public static byte[] addFirst(final byte[] array, final byte element) {
1233 return array == null ? add(array, element) : insert(0, array, element);
1234 }
1235
1236 /**
1237 * Copies the given array and adds the given element at the beginning of the new array.
1238 * <p>
1239 * The new array contains the same elements of the input array plus the given element in the first position. The
1240 * component type of the new array is the same as that of the input array.
1241 * </p>
1242 * <p>
1243 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1244 * element.
1245 * </p>
1246 * <pre>
1247 * ArrayUtils.addFirst(null, '1') = ['1']
1248 * ArrayUtils.addFirst(['1'], '0') = ['0', '1']
1249 * ArrayUtils.addFirst(['1', '0'], '1') = ['1', '1', '0']
1250 * </pre>
1251 *
1252 * @param array the array to "add" the element to, may be {@code null}.
1253 * @param element the object to add.
1254 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1255 * the input array (unless null), in which case it will have the same type as the element.
1256 * @since 3.10
1257 */
1258 public static char[] addFirst(final char[] array, final char element) {
1259 return array == null ? add(array, element) : insert(0, array, element);
1260 }
1261
1262 /**
1263 * Copies the given array and adds the given element at the beginning of the new array.
1264 * <p>
1265 * The new array contains the same elements of the input array plus the given element in the first position. The
1266 * component type of the new array is the same as that of the input array.
1267 * </p>
1268 * <p>
1269 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1270 * element.
1271 * </p>
1272 * <pre>
1273 * ArrayUtils.addFirst(null, 1) = [1]
1274 * ArrayUtils.addFirst([1], 0) = [0, 1]
1275 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1276 * </pre>
1277 *
1278 * @param array the array to "add" the element to, may be {@code null}.
1279 * @param element the object to add.
1280 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1281 * the input array (unless null), in which case it will have the same type as the element.
1282 * @since 3.10
1283 */
1284 public static double[] addFirst(final double[] array, final double element) {
1285 return array == null ? add(array, element) : insert(0, array, element);
1286 }
1287
1288 /**
1289 * Copies the given array and adds the given element at the beginning of the new array.
1290 * <p>
1291 * The new array contains the same elements of the input array plus the given element in the first position. The
1292 * component type of the new array is the same as that of the input array.
1293 * </p>
1294 * <p>
1295 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1296 * element.
1297 * </p>
1298 * <pre>
1299 * ArrayUtils.addFirst(null, 1) = [1]
1300 * ArrayUtils.addFirst([1], 0) = [0, 1]
1301 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1302 * </pre>
1303 *
1304 * @param array the array to "add" the element to, may be {@code null}.
1305 * @param element the object to add.
1306 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1307 * the input array (unless null), in which case it will have the same type as the element.
1308 * @since 3.10
1309 */
1310 public static float[] addFirst(final float[] array, final float element) {
1311 return array == null ? add(array, element) : insert(0, array, element);
1312 }
1313
1314 /**
1315 * Copies the given array and adds the given element at the beginning of the new array.
1316 * <p>
1317 * The new array contains the same elements of the input array plus the given element in the first position. The
1318 * component type of the new array is the same as that of the input array.
1319 * </p>
1320 * <p>
1321 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1322 * element.
1323 * </p>
1324 * <pre>
1325 * ArrayUtils.addFirst(null, 1) = [1]
1326 * ArrayUtils.addFirst([1], 0) = [0, 1]
1327 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1328 * </pre>
1329 *
1330 * @param array the array to "add" the element to, may be {@code null}.
1331 * @param element the object to add.
1332 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1333 * the input array (unless null), in which case it will have the same type as the element.
1334 * @since 3.10
1335 */
1336 public static int[] addFirst(final int[] array, final int element) {
1337 return array == null ? add(array, element) : insert(0, array, element);
1338 }
1339
1340 /**
1341 * Copies the given array and adds the given element at the beginning of the new array.
1342 * <p>
1343 * The new array contains the same elements of the input array plus the given element in the first position. The
1344 * component type of the new array is the same as that of the input array.
1345 * </p>
1346 * <p>
1347 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1348 * element.
1349 * </p>
1350 * <pre>
1351 * ArrayUtils.addFirst(null, 1) = [1]
1352 * ArrayUtils.addFirst([1], 0) = [0, 1]
1353 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1354 * </pre>
1355 *
1356 * @param array the array to "add" the element to, may be {@code null}.
1357 * @param element the object to add.
1358 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1359 * the input array (unless null), in which case it will have the same type as the element.
1360 * @since 3.10
1361 */
1362 public static long[] addFirst(final long[] array, final long element) {
1363 return array == null ? add(array, element) : insert(0, array, element);
1364 }
1365
1366 /**
1367 * Copies the given array and adds the given element at the beginning of the new array.
1368 * <p>
1369 * The new array contains the same elements of the input array plus the given element in the first position. The
1370 * component type of the new array is the same as that of the input array.
1371 * </p>
1372 * <p>
1373 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1374 * element.
1375 * </p>
1376 * <pre>
1377 * ArrayUtils.addFirst(null, 1) = [1]
1378 * ArrayUtils.addFirst([1], 0) = [0, 1]
1379 * ArrayUtils.addFirst([1, 0], 1) = [1, 1, 0]
1380 * </pre>
1381 *
1382 * @param array the array to "add" the element to, may be {@code null}.
1383 * @param element the object to add.
1384 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1385 * the input array (unless null), in which case it will have the same type as the element.
1386 * @since 3.10
1387 */
1388 public static short[] addFirst(final short[] array, final short element) {
1389 return array == null ? add(array, element) : insert(0, array, element);
1390 }
1391
1392 /**
1393 * Copies the given array and adds the given element at the beginning of the new array.
1394 * <p>
1395 * The new array contains the same elements of the input array plus the given element in the first position. The
1396 * component type of the new array is the same as that of the input array.
1397 * </p>
1398 * <p>
1399 * If the input array is {@code null}, a new one element array is returned whose component type is the same as the
1400 * element, unless the element itself is null, in which case the return type is Object[]
1401 * </p>
1402 * <pre>
1403 * ArrayUtils.addFirst(null, null) = Throws {@link IllegalArgumentException}
1404 * ArrayUtils.addFirst(null, "a") = ["a"]
1405 * ArrayUtils.addFirst(["a"], null) = [null, "a"]
1406 * ArrayUtils.addFirst(["a"], "b") = ["b", "a"]
1407 * ArrayUtils.addFirst(["a", "b"], "c") = ["c", "a", "b"]
1408 * </pre>
1409 *
1410 * @param <T> the component type of the array.
1411 * @param array the array to "add" the element to, may be {@code null}.
1412 * @param element the object to add, may be {@code null}.
1413 * @return A new array containing the existing elements plus the new element The returned array type will be that of
1414 * the input array (unless null), in which case it will have the same type as the element. If both are null,
1415 * an IllegalArgumentException is thrown.
1416 * @throws IllegalArgumentException if both arguments are null.
1417 * @since 3.10
1418 */
1419 public static <T> T[] addFirst(final T[] array, final T element) {
1420 return array == null ? add(array, element) : insert(0, array, element);
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 destPos starting position in the destination data.
1430 * @param length the number of array elements to be copied.
1431 * @param allocator allocates the array to populate and return.
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 int destPos, final int length, final Function<Integer, T> allocator) {
1440 return arraycopy(source, sourcePos, allocator.apply(length), destPos, length);
1441 }
1442
1443 /**
1444 * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the destination array.
1445 *
1446 * @param <T> the type.
1447 * @param source the source array.
1448 * @param sourcePos starting position in the source array.
1449 * @param destPos starting position in the destination data.
1450 * @param length the number of array elements to be copied.
1451 * @param allocator allocates the array to populate and return.
1452 * @return dest
1453 * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds.
1454 * @throws ArrayStoreException if an element in the {@code src} array could not be stored into the {@code dest} array because of a type
1455 * mismatch.
1456 * @throws NullPointerException if either {@code src} or {@code dest} is {@code null}.
1457 * @since 3.15.0
1458 */
1459 public static <T> T arraycopy(final T source, final int sourcePos, final int destPos, final int length, final Supplier<T> allocator) {
1460 return arraycopy(source, sourcePos, allocator.get(), destPos, length);
1461 }
1462
1463 /**
1464 * A fluent version of {@link System#arraycopy(Object, int, Object, int, int)} that returns the destination array.
1465 *
1466 * @param <T> the type.
1467 * @param source the source array.
1468 * @param sourcePos starting position in the source array.
1469 * @param dest the destination array.
1470 * @param destPos starting position in the destination data.
1471 * @param length the number of array elements to be copied.
1472 * @return dest
1473 * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds.
1474 * @throws ArrayStoreException if an element in the {@code src} array could not be stored into the {@code dest} array because of a type
1475 * mismatch.
1476 * @throws NullPointerException if either {@code src} or {@code dest} is {@code null}.
1477 * @since 3.15.0
1478 */
1479 public static <T> T arraycopy(final T source, final int sourcePos, final T dest, final int destPos, final int length) {
1480 System.arraycopy(source, sourcePos, dest, destPos, length);
1481 return dest;
1482 }
1483
1484 /**
1485 * Clones an array or returns {@code null}.
1486 * <p>
1487 * This method returns {@code null} for a {@code null} input array.
1488 * </p>
1489 *
1490 * @param array the array to clone, may be {@code null}.
1491 * @return the cloned array, {@code null} if {@code null} input.
1492 */
1493 public static boolean[] clone(final boolean[] array) {
1494 return array != null ? array.clone() : null;
1495 }
1496
1497 /**
1498 * Clones an array or returns {@code null}.
1499 * <p>
1500 * This method returns {@code null} for a {@code null} input array.
1501 * </p>
1502 *
1503 * @param array the array to clone, may be {@code null}.
1504 * @return the cloned array, {@code null} if {@code null} input.
1505 */
1506 public static byte[] clone(final byte[] array) {
1507 return array != null ? array.clone() : null;
1508 }
1509
1510 /**
1511 * Clones an array or returns {@code null}.
1512 * <p>
1513 * This method returns {@code null} for a {@code null} input array.
1514 * </p>
1515 *
1516 * @param array the array to clone, may be {@code null}.
1517 * @return the cloned array, {@code null} if {@code null} input.
1518 */
1519 public static char[] clone(final char[] array) {
1520 return array != null ? array.clone() : null;
1521 }
1522
1523 /**
1524 * Clones an array or returns {@code null}.
1525 * <p>
1526 * This method returns {@code null} for a {@code null} input array.
1527 * </p>
1528 *
1529 * @param array the array to clone, may be {@code null}.
1530 * @return the cloned array, {@code null} if {@code null} input.
1531 */
1532 public static double[] clone(final double[] array) {
1533 return array != null ? array.clone() : null;
1534 }
1535
1536 /**
1537 * Clones an array or returns {@code null}.
1538 * <p>
1539 * This method returns {@code null} for a {@code null} input array.
1540 * </p>
1541 *
1542 * @param array the array to clone, may be {@code null}.
1543 * @return the cloned array, {@code null} if {@code null} input.
1544 */
1545 public static float[] clone(final float[] array) {
1546 return array != null ? array.clone() : null;
1547 }
1548
1549 /**
1550 * Clones an array or returns {@code null}.
1551 * <p>
1552 * This method returns {@code null} for a {@code null} input array.
1553 * </p>
1554 *
1555 * @param array the array to clone, may be {@code null}.
1556 * @return the cloned array, {@code null} if {@code null} input.
1557 */
1558 public static int[] clone(final int[] array) {
1559 return array != null ? array.clone() : null;
1560 }
1561
1562 /**
1563 * Clones an array or returns {@code null}.
1564 * <p>
1565 * This method returns {@code null} for a {@code null} input array.
1566 * </p>
1567 *
1568 * @param array the array to clone, may be {@code null}.
1569 * @return the cloned array, {@code null} if {@code null} input.
1570 */
1571 public static long[] clone(final long[] array) {
1572 return array != null ? array.clone() : null;
1573 }
1574
1575 /**
1576 * Clones an array or returns {@code null}.
1577 * <p>
1578 * This method returns {@code null} for a {@code null} input array.
1579 * </p>
1580 *
1581 * @param array the array to clone, may be {@code null}.
1582 * @return the cloned array, {@code null} if {@code null} input.
1583 */
1584 public static short[] clone(final short[] array) {
1585 return array != null ? array.clone() : null;
1586 }
1587
1588 /**
1589 * Shallow clones an array or returns {@code null}.
1590 * <p>
1591 * The objects in the array are not cloned, thus there is no special handling for multi-dimensional arrays.
1592 * </p>
1593 * <p>
1594 * This method returns {@code null} for a {@code null} input array.
1595 * </p>
1596 *
1597 * @param <T> the component type of the array.
1598 * @param array the array to shallow clone, may be {@code null}.
1599 * @return the cloned array, {@code null} if {@code null} input.
1600 */
1601 public static <T> T[] clone(final T[] array) {
1602 return array != null ? array.clone() : null;
1603 }
1604
1605 /**
1606 * Concatenates multiple boolean arrays into a single array.
1607 * <p>
1608 * This method combines all input arrays in the order they are provided,
1609 * creating a new array that contains all elements from the input arrays.
1610 * The resulting array length is the sum of lengths of all non-null input arrays.
1611 * </p>
1612 *
1613 * @param arrays the arrays to concatenate. Can be empty, contain nulls,
1614 * or be null itself (treated as empty varargs).
1615 * @return a new boolean array containing all elements from the input arrays
1616 * in the order they appear, or an empty array if no elements are present.
1617 * @throws NullPointerException if the input array of arrays is null.
1618 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1619 * @since 3.21.0
1620 */
1621 public static boolean[] concat(boolean[]... arrays) {
1622 int totalLength = 0;
1623 for (boolean[] array : arrays) {
1624 totalLength = addExact(totalLength, array);
1625 }
1626 final boolean[] result = new boolean[totalLength];
1627 int currentPos = 0;
1628 for (boolean[] array : arrays) {
1629 if (array != null && array.length > 0) {
1630 System.arraycopy(array, 0, result, currentPos, array.length);
1631 currentPos += array.length;
1632 }
1633 }
1634 return result;
1635 }
1636
1637 /**
1638 * Concatenates multiple byte arrays into a single array.
1639 * <p>
1640 * This method combines all input arrays in the order they are provided,
1641 * creating a new array that contains all elements from the input arrays.
1642 * The resulting array length is the sum of lengths of all non-null input arrays.
1643 * </p>
1644 *
1645 * @param arrays the arrays to concatenate. Can be empty, contain nulls,
1646 * or be null itself (treated as empty varargs).
1647 * @return a new byte array containing all elements from the input arrays
1648 * in the order they appear, or an empty array if no elements are present.
1649 * @throws NullPointerException if the input array of arrays is null.
1650 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1651 * @since 3.21.0
1652 */
1653 public static byte[] concat(byte[]... arrays) {
1654 int totalLength = 0;
1655 for (byte[] array : arrays) {
1656 totalLength = addExact(totalLength, array);
1657 }
1658 final byte[] result = new byte[totalLength];
1659 int currentPos = 0;
1660 for (byte[] array : arrays) {
1661 if (array != null && array.length > 0) {
1662 System.arraycopy(array, 0, result, currentPos, array.length);
1663 currentPos += array.length;
1664 }
1665 }
1666 return result;
1667 }
1668
1669 /**
1670 * Concatenates multiple char arrays into a single array.
1671 * <p>
1672 * This method combines all input arrays in the order they are provided,
1673 * creating a new array that contains all elements from the input arrays.
1674 * The resulting array length is the sum of lengths of all non-null input arrays.
1675 * </p>
1676 *
1677 * @param arrays the arrays to concatenate. Can be empty, contain nulls,
1678 * or be null itself (treated as empty varargs).
1679 * @return a new char array containing all elements from the input arrays
1680 * in the order they appear, or an empty array if no elements are present.
1681 * @throws NullPointerException if the input array of arrays is null.
1682 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1683 * @since 3.21.0
1684 */
1685 public static char[] concat(char[]... arrays) {
1686 int totalLength = 0;
1687 for (char[] array : arrays) {
1688 totalLength = addExact(totalLength, array);
1689 }
1690 final char[] result = new char[totalLength];
1691 int currentPos = 0;
1692 for (char[] array : arrays) {
1693 if (array != null && array.length > 0) {
1694 System.arraycopy(array, 0, result, currentPos, array.length);
1695 currentPos += array.length;
1696 }
1697 }
1698 return result;
1699 }
1700
1701 /**
1702 * Concatenates multiple double arrays into a single array.
1703 * <p>
1704 * This method combines all input arrays in the order they are provided,
1705 * creating a new array that contains all elements from the input arrays.
1706 * The resulting array length is the sum of lengths of all non-null input arrays.
1707 * </p>
1708 *
1709 * @param arrays the arrays to concatenate. Can be empty, contain nulls,
1710 * or be null itself (treated as empty varargs).
1711 * @return a new double array containing all elements from the input arrays
1712 * in the order they appear, or an empty array if no elements are present.
1713 * @throws NullPointerException if the input array of arrays is null.
1714 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1715 * @since 3.21.0
1716 */
1717 public static double[] concat(double[]... arrays) {
1718 int totalLength = 0;
1719 for (double[] array : arrays) {
1720 totalLength = addExact(totalLength, array);
1721 }
1722 final double[] result = new double[totalLength];
1723 int currentPos = 0;
1724 for (double[] array : arrays) {
1725 if (array != null && array.length > 0) {
1726 System.arraycopy(array, 0, result, currentPos, array.length);
1727 currentPos += array.length;
1728 }
1729 }
1730 return result;
1731 }
1732
1733 /**
1734 * Concatenates multiple float arrays into a single array.
1735 * <p>
1736 * This method combines all input arrays in the order they are provided,
1737 * creating a new array that contains all elements from the input arrays.
1738 * The resulting array length is the sum of lengths of all non-null input arrays.
1739 * </p>
1740 *
1741 * @param arrays the arrays to concatenate. Can be empty, contain nulls,
1742 * or be null itself (treated as empty varargs).
1743 * @return a new float array containing all elements from the input arrays
1744 * in the order they appear, or an empty array if no elements are present.
1745 * @throws NullPointerException if the input array of arrays is null.
1746 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1747 * @since 3.21.0
1748 */
1749 public static float[] concat(float[]... arrays) {
1750 int totalLength = 0;
1751 for (float[] array : arrays) {
1752 totalLength = addExact(totalLength, array);
1753 }
1754 final float[] result = new float[totalLength];
1755 int currentPos = 0;
1756 for (float[] array : arrays) {
1757 if (array != null && array.length > 0) {
1758 System.arraycopy(array, 0, result, currentPos, array.length);
1759 currentPos += array.length;
1760 }
1761 }
1762 return result;
1763 }
1764
1765 /**
1766 * Concatenates multiple int arrays into a single array.
1767 * <p>
1768 * This method combines all input arrays in the order they are provided,
1769 * creating a new array that contains all elements from the input arrays.
1770 * The resulting array length is the sum of lengths of all non-null input arrays.
1771 * </p>
1772 *
1773 * @param arrays the arrays to concatenate. Can be empty, contain nulls,
1774 * or be null itself (treated as empty varargs).
1775 * @return a new int array containing all elements from the input arrays
1776 * in the order they appear, or an empty array if no elements are present.
1777 * @throws NullPointerException if the input array of arrays is null.
1778 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1779 * @since 3.21.0
1780 */
1781 public static int[] concat(int[]... arrays) {
1782 int totalLength = 0;
1783 for (int[] array : arrays) {
1784 totalLength = addExact(totalLength, array);
1785 }
1786 final int[] result = new int[totalLength];
1787 int currentPos = 0;
1788 for (int[] array : arrays) {
1789 if (array != null && array.length > 0) {
1790 System.arraycopy(array, 0, result, currentPos, array.length);
1791 currentPos += array.length;
1792 }
1793 }
1794 return result;
1795 }
1796
1797 /**
1798 * Concatenates multiple long arrays into a single array.
1799 * <p>
1800 * This method combines all input arrays in the order they are provided,
1801 * creating a new array that contains all elements from the input arrays.
1802 * The resulting array length is the sum of lengths of all non-null input arrays.
1803 * </p>
1804 *
1805 * @param arrays the arrays to concatenate. Can be empty, contain nulls,
1806 * or be null itself (treated as empty varargs).
1807 * @return a new long array containing all elements from the input arrays
1808 * in the order they appear, or an empty array if no elements are present.
1809 * @throws NullPointerException if the input array of arrays is null.
1810 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1811 * @since 3.21.0
1812 */
1813 public static long[] concat(long[]... arrays) {
1814 int totalLength = 0;
1815 for (long[] array : arrays) {
1816 totalLength = addExact(totalLength, array);
1817 }
1818 final long[] result = new long[totalLength];
1819 int currentPos = 0;
1820 for (long[] array : arrays) {
1821 if (array != null && array.length > 0) {
1822 System.arraycopy(array, 0, result, currentPos, array.length);
1823 currentPos += array.length;
1824 }
1825 }
1826 return result;
1827 }
1828
1829 /**
1830 * Concatenates multiple short arrays into a single array.
1831 * <p>
1832 * This method combines all input arrays in the order they are provided,
1833 * creating a new array that contains all elements from the input arrays.
1834 * The resulting array length is the sum of lengths of all non-null input arrays.
1835 * </p>
1836 *
1837 * @param arrays the arrays to concatenate. Can be empty, contain nulls,
1838 * or be null itself (treated as empty varargs).
1839 * @return a new short array containing all elements from the input arrays
1840 * in the order they appear, or an empty array if no elements are present.
1841 * @throws NullPointerException if the input array of arrays is null.
1842 * @throws IllegalArgumentException if total arrays length exceed {@link ArrayUtils#SAFE_MAX_ARRAY_LENGTH}.
1843 * @since 3.21.0
1844 */
1845 public static short[] concat(short[]... arrays) {
1846 int totalLength = 0;
1847 for (short[] array : arrays) {
1848 totalLength = addExact(totalLength, array);
1849 }
1850 final short[] result = new short[totalLength];
1851 int currentPos = 0;
1852 for (short[] array : arrays) {
1853 if (array != null && array.length > 0) {
1854 System.arraycopy(array, 0, result, currentPos, array.length);
1855 currentPos += array.length;
1856 }
1857 }
1858 return result;
1859 }
1860
1861 /**
1862 * Checks if the value is in the given array.
1863 * <p>
1864 * The method returns {@code false} if a {@code null} array is passed in.
1865 * </p>
1866 *
1867 * @param array the array to search.
1868 * @param valueToFind the value to find.
1869 * @return {@code true} if the array contains the object.
1870 */
1871 public static boolean contains(final boolean[] array, final boolean valueToFind) {
1872 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1873 }
1874
1875 /**
1876 * Checks if the value is in the given array.
1877 * <p>
1878 * The method returns {@code false} if a {@code null} array is passed in.
1879 * </p>
1880 * <p>
1881 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1882 * {@link Arrays#sort(byte[])} and {@link Arrays#binarySearch(byte[], byte)}.
1883 * </p>
1884 *
1885 * @param array the array to search.
1886 * @param valueToFind the value to find.
1887 * @return {@code true} if the array contains the object.
1888 */
1889 public static boolean contains(final byte[] array, final byte valueToFind) {
1890 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1891 }
1892
1893 /**
1894 * Checks if the value is in the given array.
1895 * <p>
1896 * The method returns {@code false} if a {@code null} array is passed in.
1897 * </p>
1898 * <p>
1899 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1900 * {@link Arrays#sort(char[])} and {@link Arrays#binarySearch(char[], char)}.
1901 * </p>
1902 *
1903 * @param array the array to search.
1904 * @param valueToFind the value to find.
1905 * @return {@code true} if the array contains the object.
1906 * @since 2.1
1907 */
1908 public static boolean contains(final char[] array, final char valueToFind) {
1909 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1910 }
1911
1912 /**
1913 * Checks if the value is in the given array.
1914 * <p>
1915 * The method returns {@code false} if a {@code null} array is passed in.
1916 * </p>
1917 * <p>
1918 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1919 * {@link Arrays#sort(double[])} and {@link Arrays#binarySearch(double[], double)}.
1920 * </p>
1921 *
1922 * @param array the array to search.
1923 * @param valueToFind the value to find.
1924 * @return {@code true} if the array contains the object.
1925 */
1926 public static boolean contains(final double[] array, final double valueToFind) {
1927 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1928 }
1929
1930 /**
1931 * Checks if a value falling within the given tolerance is in the
1932 * given array. If the array contains a value within the inclusive range
1933 * defined by (value - tolerance) to (value + tolerance).
1934 * <p>
1935 * The method returns {@code false} if a {@code null} array
1936 * is passed in.
1937 * </p>
1938 * <p>
1939 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1940 * {@link Arrays#sort(double[])} and {@link Arrays#binarySearch(double[], double)}.
1941 * </p>
1942 *
1943 * @param array the array to search.
1944 * @param valueToFind the value to find.
1945 * @param tolerance the array contains the tolerance of the search.
1946 * @return true if value falling within tolerance is in array.
1947 */
1948 public static boolean contains(final double[] array, final double valueToFind, final double tolerance) {
1949 return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
1950 }
1951
1952 /**
1953 * Checks if the value is in the given array.
1954 * <p>
1955 * The method returns {@code false} if a {@code null} array is passed in.
1956 * </p>
1957 * <p>
1958 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1959 * {@link Arrays#sort(float[])} and {@link Arrays#binarySearch(float[], float)}.
1960 * </p>
1961 *
1962 * @param array the array to search.
1963 * @param valueToFind the value to find.
1964 * @return {@code true} if the array contains the object.
1965 */
1966 public static boolean contains(final float[] array, final float valueToFind) {
1967 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1968 }
1969
1970 /**
1971 * Checks if the value is in the given array.
1972 * <p>
1973 * The method returns {@code false} if a {@code null} array is passed in.
1974 * </p>
1975 * <p>
1976 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1977 * {@link Arrays#sort(int[])} and {@link Arrays#binarySearch(int[], int)}.
1978 * </p>
1979 *
1980 * @param array the array to search.
1981 * @param valueToFind the value to find.
1982 * @return {@code true} if the array contains the object.
1983 */
1984 public static boolean contains(final int[] array, final int valueToFind) {
1985 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1986 }
1987
1988 /**
1989 * Checks if the value is in the given array.
1990 * <p>
1991 * The method returns {@code false} if a {@code null} array is passed in.
1992 * </p>
1993 * <p>
1994 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
1995 * {@link Arrays#sort(long[])} and {@link Arrays#binarySearch(long[], long)}.
1996 * </p>
1997 *
1998 * @param array the array to search.
1999 * @param valueToFind the value to find.
2000 * @return {@code true} if the array contains the object.
2001 */
2002 public static boolean contains(final long[] array, final long valueToFind) {
2003 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2004 }
2005
2006 /**
2007 * Checks if the object is in the given array.
2008 * <p>
2009 * The method returns {@code false} if a {@code null} array is passed in.
2010 * </p>
2011 * <p>
2012 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
2013 * {@link Arrays#sort(Object[], Comparator)} and {@link Arrays#binarySearch(Object[], Object)}.
2014 * </p>
2015 *
2016 * @param array the array to search, may be {@code null}.
2017 * @param objectToFind the object to find, may be {@code null}.
2018 * @return {@code true} if the array contains the object.
2019 */
2020 public static boolean contains(final Object[] array, final Object objectToFind) {
2021 return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
2022 }
2023
2024 /**
2025 * Checks if the value is in the given array.
2026 * <p>
2027 * The method returns {@code false} if a {@code null} array is passed in.
2028 * </p>
2029 * <p>
2030 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
2031 * {@link Arrays#sort(short[])} and {@link Arrays#binarySearch(short[], short)}.
2032 * </p>
2033 *
2034 * @param array the array to search.
2035 * @param valueToFind the value to find.
2036 * @return {@code true} if the array contains the object.
2037 */
2038 public static boolean contains(final short[] array, final short valueToFind) {
2039 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2040 }
2041
2042 /**
2043 * Checks if any of the ints are in the given array.
2044 * <p>
2045 * The method returns {@code false} if a {@code null} array is passed in.
2046 * </p>
2047 * <p>
2048 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
2049 * {@link Arrays#sort(int[])} and {@link Arrays#binarySearch(int[], int)}.
2050 * </p>
2051 *
2052 * @param array the array to search.
2053 * @param objectsToFind any of the ints to find.
2054 * @return {@code true} if the array contains any of the ints.
2055 * @since 3.18.0
2056 */
2057 public static boolean containsAny(final int[] array, final int... objectsToFind) {
2058 return IntStreams.of(objectsToFind).anyMatch(e -> contains(array, e));
2059 }
2060
2061 /**
2062 * Checks if any of the objects are in the given array.
2063 * <p>
2064 * The method returns {@code false} if a {@code null} array is passed in.
2065 * </p>
2066 * <p>
2067 * If the {@code array} elements you are searching implement {@link Comparator}, consider whether it is worth using
2068 * {@link Arrays#sort(Object[], Comparator)} and {@link Arrays#binarySearch(Object[], Object)}.
2069 * </p>
2070 *
2071 * @param array the array to search, may be {@code null}.
2072 * @param objectsToFind any of the objects to find, may be {@code null}.
2073 * @return {@code true} if the array contains any of the objects.
2074 * @since 3.13.0
2075 */
2076 public static boolean containsAny(final Object[] array, final Object... objectsToFind) {
2077 return Streams.of(objectsToFind).anyMatch(e -> contains(array, e));
2078 }
2079
2080 /**
2081 * Returns a copy of the given array of size 1 greater than the argument.
2082 * The last value of the array is left to the default value.
2083 *
2084 * @param array The array to copy, must not be {@code null}.
2085 * @param newArrayComponentType If {@code array} is {@code null}, create a
2086 * size 1 array of this type.
2087 * @return A new copy of the array of size 1 greater than the input.
2088 */
2089 private static Object copyArrayGrow1(final Object array, final Class<?> newArrayComponentType) {
2090 if (array != null) {
2091 final int arrayLength = Array.getLength(array);
2092 final Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
2093 System.arraycopy(array, 0, newArray, 0, arrayLength);
2094 return newArray;
2095 }
2096 return Array.newInstance(newArrayComponentType, 1);
2097 }
2098
2099 /**
2100 * Gets the nTh element of an array or null if the index is out of bounds or the array is null.
2101 *
2102 * @param <T> The type of array elements.
2103 * @param array The array to index.
2104 * @param index The index.
2105 * @return the nTh element of an array or null if the index is out of bounds or the array is null.
2106 * @since 3.11
2107 */
2108 public static <T> T get(final T[] array, final int index) {
2109 return get(array, index, null);
2110 }
2111
2112 /**
2113 * Gets the nTh element of an array or a default value if the index is out of bounds.
2114 *
2115 * @param <T> The type of array elements.
2116 * @param array The array to index.
2117 * @param index The index.
2118 * @param defaultValue The return value of the given index is out of bounds.
2119 * @return the nTh element of an array or a default value if the index is out of bounds.
2120 * @since 3.11
2121 */
2122 public static <T> T get(final T[] array, final int index, final T defaultValue) {
2123 return isArrayIndexValid(array, index) ? array[index] : defaultValue;
2124 }
2125
2126 /**
2127 * Gets an array's component type.
2128 *
2129 * @param <T> The array type.
2130 * @param array The array.
2131 * @return The component type.
2132 * @since 3.13.0
2133 */
2134 public static <T> Class<T> getComponentType(final T[] array) {
2135 return ClassUtils.getComponentType(ObjectUtils.getClass(array));
2136 }
2137
2138 /**
2139 * Gets the number of dimensions of an array.
2140 * <p>
2141 * The <a href="https://docs.oracle.com/javase/specs/jvms/se25/html/jvms-4.html#jvms-4.3">JVM specification</a> limits the number of dimensions to 255.
2142 * </p>
2143 *
2144 * @param array the array, may be {@code null}.
2145 * @return The number of dimensions, 0 if the input is null or not an array. The JVM specification limits the number of dimensions to 255.
2146 * @since 3.21.0
2147 * @see <a href="https://docs.oracle.com/javase/specs/jvms/se25/html/jvms-4.html#jvms-4.3">JVM specification Field Descriptors</a>
2148 */
2149 public static int getDimensions(final Object array) {
2150 int dimensions = 0;
2151 if (array != null) {
2152 Class<?> arrayClass = array.getClass();
2153 while (arrayClass.isArray()) {
2154 dimensions++;
2155 arrayClass = arrayClass.getComponentType();
2156 }
2157 }
2158 return dimensions;
2159 }
2160
2161 /**
2162 * Gets the length of the specified array.
2163 * This method handles {@link Object} arrays and primitive arrays.
2164 * <p>
2165 * If the input array is {@code null}, {@code 0} is returned.
2166 * </p>
2167 * <pre>
2168 * ArrayUtils.getLength(null) = 0
2169 * ArrayUtils.getLength([]) = 0
2170 * ArrayUtils.getLength([null]) = 1
2171 * ArrayUtils.getLength([true, false]) = 2
2172 * ArrayUtils.getLength([1, 2, 3]) = 3
2173 * ArrayUtils.getLength(["a", "b", "c"]) = 3
2174 * </pre>
2175 *
2176 * @param array the array to retrieve the length from, may be {@code null}.
2177 * @return The length of the array, or {@code 0} if the array is {@code null}.
2178 * @throws IllegalArgumentException if the object argument is not an array.
2179 * @since 2.1
2180 */
2181 public static int getLength(final Object array) {
2182 return array != null ? Array.getLength(array) : 0;
2183 }
2184
2185 /**
2186 * Gets a hash code for an array handling multidimensional arrays correctly.
2187 * <p>
2188 * Multi-dimensional primitive arrays are also handled correctly by this method.
2189 * </p>
2190 *
2191 * @param array the array to get a hash code for, {@code null} returns zero.
2192 * @return a hash code for the array.
2193 */
2194 public static int hashCode(final Object array) {
2195 return new HashCodeBuilder().append(array).toHashCode();
2196 }
2197
2198 static <K> void increment(final Map<K, MutableInt> occurrences, final K boxed) {
2199 occurrences.computeIfAbsent(boxed, k -> new MutableInt()).increment();
2200 }
2201
2202 /**
2203 * Finds the indices of the given value in the array.
2204 * <p>
2205 * This method returns an empty BitSet for a {@code null} input array.
2206 * </p>
2207 *
2208 * @param array the array to search for the object, may be {@code null}.
2209 * @param valueToFind the value to find.
2210 * @return a BitSet of all the indices of the value within the array,
2211 * an empty BitSet if not found or {@code null} array input.
2212 * @since 3.10
2213 */
2214 public static BitSet indexesOf(final boolean[] array, final boolean valueToFind) {
2215 return indexesOf(array, valueToFind, 0);
2216 }
2217
2218 /**
2219 * Finds the indices of the given value in the array starting at the given index.
2220 * <p>
2221 * This method returns an empty BitSet for a {@code null} input array.
2222 * </p>
2223 * <p>
2224 * A negative startIndex is treated as zero. A startIndex larger than the array length will return an empty BitSet ({@code -1}).
2225 * </p>
2226 *
2227 * @param array the array to search for the object, may be {@code null}.
2228 * @param valueToFind the value to find.
2229 * @param startIndex the index to start searching.
2230 * @return a BitSet of all the indices of the value within the array, an empty BitSet if not found or {@code null} array input.
2231 * @since 3.10
2232 */
2233 public static BitSet indexesOf(final boolean[] array, final boolean valueToFind, int startIndex) {
2234 final BitSet bitSet = new BitSet();
2235 if (array != null) {
2236 while (startIndex < array.length) {
2237 startIndex = indexOf(array, valueToFind, startIndex);
2238 if (startIndex == INDEX_NOT_FOUND) {
2239 break;
2240 }
2241 bitSet.set(startIndex);
2242 ++startIndex;
2243 }
2244 }
2245 return bitSet;
2246 }
2247
2248 /**
2249 * Finds the indices of the given value in the array.
2250 *
2251 * <p>
2252 * This method returns an empty BitSet for a {@code null} input array.
2253 * </p>
2254 *
2255 * @param array the array to search for the object, may be {@code null}.
2256 * @param valueToFind the value to find.
2257 * @return a BitSet of all the indices of the value within the array, an empty BitSet if not found or {@code null} array input.
2258 * @since 3.10
2259 */
2260 public static BitSet indexesOf(final byte[] array, final byte valueToFind) {
2261 return indexesOf(array, valueToFind, 0);
2262 }
2263
2264 /**
2265 * Finds the indices of the given value in the array starting at the given index.
2266 *
2267 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2268 *
2269 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2270 * length will return an empty BitSet.</p>
2271 *
2272 * @param array the array to search for the object, may be {@code null}.
2273 * @param valueToFind the value to find.
2274 * @param startIndex the index to start searching.
2275 * @return a BitSet of all the indices of the value within the array,
2276 * an empty BitSet if not found or {@code null} array input.
2277 * @since 3.10
2278 */
2279 public static BitSet indexesOf(final byte[] array, final byte valueToFind, int startIndex) {
2280 final BitSet bitSet = new BitSet();
2281 if (array != null) {
2282 while (startIndex < array.length) {
2283 startIndex = indexOf(array, valueToFind, startIndex);
2284 if (startIndex == INDEX_NOT_FOUND) {
2285 break;
2286 }
2287 bitSet.set(startIndex);
2288 ++startIndex;
2289 }
2290 }
2291 return bitSet;
2292 }
2293
2294 /**
2295 * Finds the indices of the given value in the array.
2296 *
2297 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2298 *
2299 * @param array the array to search for the object, may be {@code null}.
2300 * @param valueToFind the value to find.
2301 * @return a BitSet of all the indices of the value within the array,
2302 * an empty BitSet if not found or {@code null} array input.
2303 * @since 3.10
2304 */
2305 public static BitSet indexesOf(final char[] array, final char valueToFind) {
2306 return indexesOf(array, valueToFind, 0);
2307 }
2308
2309 /**
2310 * Finds the indices of the given value in the array starting at the given index.
2311 *
2312 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2313 *
2314 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2315 * length will return an empty BitSet.</p>
2316 *
2317 * @param array the array to search for the object, may be {@code null}.
2318 * @param valueToFind the value to find.
2319 * @param startIndex the index to start searching.
2320 * @return a BitSet of all the indices of the value within the array,
2321 * an empty BitSet if not found or {@code null} array input.
2322 * @since 3.10
2323 */
2324 public static BitSet indexesOf(final char[] array, final char valueToFind, int startIndex) {
2325 final BitSet bitSet = new BitSet();
2326 if (array != null) {
2327 while (startIndex < array.length) {
2328 startIndex = indexOf(array, valueToFind, startIndex);
2329 if (startIndex == INDEX_NOT_FOUND) {
2330 break;
2331 }
2332 bitSet.set(startIndex);
2333 ++startIndex;
2334 }
2335 }
2336 return bitSet;
2337 }
2338
2339 /**
2340 * Finds the indices of the given value in the array.
2341 *
2342 * <p>This method returns empty BitSet for a {@code null} input array.</p>
2343 *
2344 * @param array the array to search for the object, may be {@code null}.
2345 * @param valueToFind the value to find.
2346 * @return a BitSet of all the indices of the value within the array,
2347 * an empty BitSet if not found or {@code null} array input.
2348 * @since 3.10
2349 */
2350 public static BitSet indexesOf(final double[] array, final double valueToFind) {
2351 return indexesOf(array, valueToFind, 0);
2352 }
2353
2354 /**
2355 * Finds the indices of the given value within a given tolerance in the array.
2356 *
2357 * <p>
2358 * This method will return all the indices of the value which fall between the region
2359 * defined by valueToFind - tolerance and valueToFind + tolerance, each time between the nearest integers.
2360 * </p>
2361 *
2362 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2363 *
2364 * @param array the array to search for the object, may be {@code null}.
2365 * @param valueToFind the value to find.
2366 * @param tolerance tolerance of the search.
2367 * @return a BitSet of all the indices of the value within the array,
2368 * an empty BitSet if not found or {@code null} array input.
2369 * @since 3.10
2370 */
2371 public static BitSet indexesOf(final double[] array, final double valueToFind, final double tolerance) {
2372 return indexesOf(array, valueToFind, 0, tolerance);
2373 }
2374
2375 /**
2376 * Finds the indices of the given value in the array starting at the given index.
2377 *
2378 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2379 *
2380 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2381 * length will return an empty BitSet.</p>
2382 *
2383 * @param array the array to search for the object, may be {@code null}.
2384 * @param valueToFind the value to find.
2385 * @param startIndex the index to start searching.
2386 * @return a BitSet of the indices of the value within the array,
2387 * an empty BitSet if not found or {@code null} array input.
2388 * @since 3.10
2389 */
2390 public static BitSet indexesOf(final double[] array, final double valueToFind, int startIndex) {
2391 final BitSet bitSet = new BitSet();
2392 if (array != null) {
2393 while (startIndex < array.length) {
2394 startIndex = indexOf(array, valueToFind, startIndex);
2395 if (startIndex == INDEX_NOT_FOUND) {
2396 break;
2397 }
2398 bitSet.set(startIndex);
2399 ++startIndex;
2400 }
2401 }
2402 return bitSet;
2403 }
2404
2405 /**
2406 * Finds the indices of the given value in the array starting at the given index.
2407 *
2408 * <p>
2409 * This method will return the indices of the values which fall between the region
2410 * defined by valueToFind - tolerance and valueToFind + tolerance, between the nearest integers.
2411 * </p>
2412 *
2413 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2414 *
2415 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2416 * length will return an empty BitSet.</p>
2417 *
2418 * @param array the array to search for the object, may be {@code null}.
2419 * @param valueToFind the value to find.
2420 * @param startIndex the index to start searching.
2421 * @param tolerance tolerance of the search.
2422 * @return a BitSet of the indices of the value within the array,
2423 * an empty BitSet if not found or {@code null} array input.
2424 * @since 3.10
2425 */
2426 public static BitSet indexesOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
2427 final BitSet bitSet = new BitSet();
2428 if (array != null) {
2429 while (startIndex < array.length) {
2430 startIndex = indexOf(array, valueToFind, startIndex, tolerance);
2431 if (startIndex == INDEX_NOT_FOUND) {
2432 break;
2433 }
2434 bitSet.set(startIndex);
2435 ++startIndex;
2436 }
2437 }
2438 return bitSet;
2439 }
2440
2441 /**
2442 * Finds the indices of the given value in the array.
2443 *
2444 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2445 *
2446 * @param array the array to search for the object, may be {@code null}.
2447 * @param valueToFind the value to find.
2448 * @return a BitSet of all the indices of the value within the array,
2449 * an empty BitSet if not found or {@code null} array input.
2450 * @since 3.10
2451 */
2452 public static BitSet indexesOf(final float[] array, final float valueToFind) {
2453 return indexesOf(array, valueToFind, 0);
2454 }
2455
2456 /**
2457 * Finds the indices of the given value in the array starting at the given index.
2458 *
2459 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2460 *
2461 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2462 * length will return empty BitSet.</p>
2463 *
2464 * @param array the array to search for the object, may be {@code null}.
2465 * @param valueToFind the value to find.
2466 * @param startIndex the index to start searching.
2467 * @return a BitSet of all the indices of the value within the array,
2468 * an empty BitSet if not found or {@code null} array input.
2469 * @since 3.10
2470 */
2471 public static BitSet indexesOf(final float[] array, final float valueToFind, int startIndex) {
2472 final BitSet bitSet = new BitSet();
2473 if (array != null) {
2474 while (startIndex < array.length) {
2475 startIndex = indexOf(array, valueToFind, startIndex);
2476 if (startIndex == INDEX_NOT_FOUND) {
2477 break;
2478 }
2479 bitSet.set(startIndex);
2480 ++startIndex;
2481 }
2482 }
2483 return bitSet;
2484 }
2485
2486 /**
2487 * Finds the indices of the given value in the array.
2488 *
2489 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2490 *
2491 * @param array the array to search for the object, may be {@code null}.
2492 * @param valueToFind the value to find.
2493 * @return a BitSet of all the indices of the value within the array,
2494 * an empty BitSet if not found or {@code null} array input.
2495 * @since 3.10
2496 */
2497 public static BitSet indexesOf(final int[] array, final int valueToFind) {
2498 return indexesOf(array, valueToFind, 0);
2499 }
2500
2501 /**
2502 * Finds the indices of the given value in the array starting at the given index.
2503 *
2504 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2505 *
2506 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2507 * length will return an empty BitSet.</p>
2508 *
2509 * @param array the array to search for the object, may be {@code null}.
2510 * @param valueToFind the value to find.
2511 * @param startIndex the index to start searching.
2512 * @return a BitSet of all the indices of the value within the array,
2513 * an empty BitSet if not found or {@code null} array input.
2514 * @since 3.10
2515 */
2516 public static BitSet indexesOf(final int[] array, final int valueToFind, int startIndex) {
2517 final BitSet bitSet = new BitSet();
2518 if (array != null) {
2519 while (startIndex < array.length) {
2520 startIndex = indexOf(array, valueToFind, startIndex);
2521 if (startIndex == INDEX_NOT_FOUND) {
2522 break;
2523 }
2524 bitSet.set(startIndex);
2525 ++startIndex;
2526 }
2527 }
2528 return bitSet;
2529 }
2530
2531 /**
2532 * Finds the indices of the given value in the array.
2533 *
2534 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2535 *
2536 * @param array the array to search for the object, may be {@code null}.
2537 * @param valueToFind the value to find.
2538 * @return a BitSet of all the indices of the value within the array,
2539 * an empty BitSet if not found or {@code null} array input.
2540 * @since 3.10
2541 */
2542 public static BitSet indexesOf(final long[] array, final long valueToFind) {
2543 return indexesOf(array, valueToFind, 0);
2544 }
2545
2546 /**
2547 * Finds the indices of the given value in the array starting at the given index.
2548 *
2549 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2550 *
2551 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2552 * length will return an empty BitSet.</p>
2553 *
2554 * @param array the array to search for the object, may be {@code null}.
2555 * @param valueToFind the value to find.
2556 * @param startIndex the index to start searching.
2557 * @return a BitSet of all the indices of the value within the array,
2558 * an empty BitSet if not found or {@code null} array input.
2559 * @since 3.10
2560 */
2561 public static BitSet indexesOf(final long[] array, final long valueToFind, int startIndex) {
2562 final BitSet bitSet = new BitSet();
2563 if (array != null) {
2564 while (startIndex < array.length) {
2565 startIndex = indexOf(array, valueToFind, startIndex);
2566 if (startIndex == INDEX_NOT_FOUND) {
2567 break;
2568 }
2569 bitSet.set(startIndex);
2570 ++startIndex;
2571 }
2572 }
2573 return bitSet;
2574 }
2575
2576 /**
2577 * Finds the indices of the given object in the array.
2578 *
2579 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2580 *
2581 * @param array the array to search for the object, may be {@code null}.
2582 * @param objectToFind the object to find, may be {@code null}.
2583 * @return a BitSet of all the indices of the object within the array,
2584 * an empty BitSet if not found or {@code null} array input.
2585 * @since 3.10
2586 */
2587 public static BitSet indexesOf(final Object[] array, final Object objectToFind) {
2588 return indexesOf(array, objectToFind, 0);
2589 }
2590
2591 /**
2592 * Finds the indices of the given object in the array starting at the given index.
2593 *
2594 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2595 *
2596 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2597 * length will return an empty BitSet.</p>
2598 *
2599 * @param array the array to search for the object, may be {@code null}.
2600 * @param objectToFind the object to find, may be {@code null}.
2601 * @param startIndex the index to start searching.
2602 * @return a BitSet of all the indices of the object within the array starting at the index,
2603 * an empty BitSet if not found or {@code null} array input.
2604 * @since 3.10
2605 */
2606 public static BitSet indexesOf(final Object[] array, final Object objectToFind, int startIndex) {
2607 final BitSet bitSet = new BitSet();
2608 if (array != null) {
2609 while (startIndex < array.length) {
2610 startIndex = indexOf(array, objectToFind, startIndex);
2611 if (startIndex == INDEX_NOT_FOUND) {
2612 break;
2613 }
2614 bitSet.set(startIndex);
2615 ++startIndex;
2616 }
2617 }
2618 return bitSet;
2619 }
2620
2621 /**
2622 * Finds the indices of the given value in the array.
2623 *
2624 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2625 *
2626 * @param array the array to search for the object, may be {@code null}.
2627 * @param valueToFind the value to find.
2628 * @return a BitSet of all the indices of the value within the array,
2629 * an empty BitSet if not found or {@code null} array input.
2630 * @since 3.10
2631 */
2632 public static BitSet indexesOf(final short[] array, final short valueToFind) {
2633 return indexesOf(array, valueToFind, 0);
2634 }
2635
2636 /**
2637 * Finds the indices of the given value in the array starting at the given index.
2638 *
2639 * <p>This method returns an empty BitSet for a {@code null} input array.</p>
2640 *
2641 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2642 * length will return an empty BitSet.</p>
2643 *
2644 * @param array the array to search for the object, may be {@code null}.
2645 * @param valueToFind the value to find.
2646 * @param startIndex the index to start searching.
2647 * @return a BitSet of all the indices of the value within the array,
2648 * an empty BitSet if not found or {@code null} array input.
2649 * @since 3.10
2650 */
2651 public static BitSet indexesOf(final short[] array, final short valueToFind, int startIndex) {
2652 final BitSet bitSet = new BitSet();
2653 if (array != null) {
2654 while (startIndex < array.length) {
2655 startIndex = indexOf(array, valueToFind, startIndex);
2656 if (startIndex == INDEX_NOT_FOUND) {
2657 break;
2658 }
2659 bitSet.set(startIndex);
2660 ++startIndex;
2661 }
2662 }
2663 return bitSet;
2664 }
2665
2666 /**
2667 * Finds the index of the given value in the array.
2668 * <p>
2669 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2670 * </p>
2671 *
2672 * @param array the array to search for the object, may be {@code null}.
2673 * @param valueToFind the value to find.
2674 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2675 */
2676 public static int indexOf(final boolean[] array, final boolean valueToFind) {
2677 return indexOf(array, valueToFind, 0);
2678 }
2679
2680 /**
2681 * Finds the index of the given value in the array starting at the given index.
2682 * <p>
2683 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2684 * </p>
2685 * <p>
2686 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2687 * </p>
2688 *
2689 * @param array the array to search for the object, may be {@code null}.
2690 * @param valueToFind the value to find.
2691 * @param startIndex the index to start searching.
2692 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2693 */
2694 public static int indexOf(final boolean[] array, final boolean valueToFind, final int startIndex) {
2695 if (isEmpty(array)) {
2696 return INDEX_NOT_FOUND;
2697 }
2698 for (int i = max0(startIndex); i < array.length; i++) {
2699 if (valueToFind == array[i]) {
2700 return i;
2701 }
2702 }
2703 return INDEX_NOT_FOUND;
2704 }
2705
2706 /**
2707 * Finds the index of the given value in the array.
2708 * <p>
2709 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2710 * </p>
2711 *
2712 * @param array the array to search for the object, may be {@code null}.
2713 * @param valueToFind the value to find.
2714 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2715 */
2716 public static int indexOf(final byte[] array, final byte valueToFind) {
2717 return indexOf(array, valueToFind, 0);
2718 }
2719
2720 /**
2721 * Finds the index of the given value in the array starting at the given index.
2722 * <p>
2723 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2724 * </p>
2725 * <p>
2726 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2727 * </p>
2728 *
2729 * @param array the array to search for the object, may be {@code null}.
2730 * @param valueToFind the value to find.
2731 * @param startIndex the index to start searching.
2732 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2733 */
2734 public static int indexOf(final byte[] array, final byte valueToFind, final int startIndex) {
2735 if (isEmpty(array)) {
2736 return INDEX_NOT_FOUND;
2737 }
2738 for (int i = max0(startIndex); i < array.length; i++) {
2739 if (valueToFind == array[i]) {
2740 return i;
2741 }
2742 }
2743 return INDEX_NOT_FOUND;
2744 }
2745
2746 /**
2747 * Finds the index of the given value in the array.
2748 * <p>
2749 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2750 * </p>
2751 *
2752 * @param array the array to search for the object, may be {@code null}.
2753 * @param valueToFind the value to find.
2754 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2755 * @since 2.1
2756 */
2757 public static int indexOf(final char[] array, final char valueToFind) {
2758 return indexOf(array, valueToFind, 0);
2759 }
2760
2761 /**
2762 * Finds the index of the given value in the array starting at the given index.
2763 * <p>
2764 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2765 * </p>
2766 * <p>
2767 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2768 * </p>
2769 *
2770 * @param array the array to search for the object, may be {@code null}.
2771 * @param valueToFind the value to find.
2772 * @param startIndex the index to start searching.
2773 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2774 * @since 2.1
2775 */
2776 public static int indexOf(final char[] array, final char valueToFind, final int startIndex) {
2777 if (isEmpty(array)) {
2778 return INDEX_NOT_FOUND;
2779 }
2780 for (int i = max0(startIndex); i < array.length; i++) {
2781 if (valueToFind == array[i]) {
2782 return i;
2783 }
2784 }
2785 return INDEX_NOT_FOUND;
2786 }
2787
2788 /**
2789 * Finds the index of the given value in the array.
2790 * <p>
2791 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2792 * </p>
2793 *
2794 * @param array the array to search for the object, may be {@code null}.
2795 * @param valueToFind the value to find.
2796 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2797 */
2798 public static int indexOf(final double[] array, final double valueToFind) {
2799 return indexOf(array, valueToFind, 0);
2800 }
2801
2802 /**
2803 * Finds the index of the given value within a given tolerance in the array. This method will return the index of the first value which falls between the
2804 * region defined by valueToFind - tolerance and valueToFind + tolerance.
2805 * <p>
2806 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2807 * </p>
2808 *
2809 * @param array the array to search for the object, may be {@code null}.
2810 * @param valueToFind the value to find.
2811 * @param tolerance tolerance of the search.
2812 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2813 */
2814 public static int indexOf(final double[] array, final double valueToFind, final double tolerance) {
2815 return indexOf(array, valueToFind, 0, tolerance);
2816 }
2817
2818 /**
2819 * Finds the index of the given value in the array starting at the given index.
2820 * <p>
2821 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2822 * </p>
2823 * <p>
2824 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2825 * </p>
2826 *
2827 * @param array the array to search for the object, may be {@code null}.
2828 * @param valueToFind the value to find.
2829 * @param startIndex the index to start searching.
2830 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2831 */
2832 public static int indexOf(final double[] array, final double valueToFind, final int startIndex) {
2833 if (Double.isNaN(valueToFind)) {
2834 return indexOfNaN(array, startIndex);
2835 }
2836 if (isEmpty(array)) {
2837 return INDEX_NOT_FOUND;
2838 }
2839 for (int i = max0(startIndex); i < array.length; i++) {
2840 if (valueToFind == array[i]) {
2841 return i;
2842 }
2843 }
2844 return INDEX_NOT_FOUND;
2845 }
2846
2847 /**
2848 * Finds the index of the given value in the array starting at the given index. This method will return the index of the first value which falls between the
2849 * region defined by valueToFind - tolerance and valueToFind + tolerance.
2850 * <p>
2851 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2852 * </p>
2853 * <p>
2854 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2855 * </p>
2856 *
2857 * @param array the array to search for the object, may be {@code null}.
2858 * @param valueToFind the value to find.
2859 * @param startIndex the index to start searching.
2860 * @param tolerance tolerance of the search.
2861 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2862 */
2863 public static int indexOf(final double[] array, final double valueToFind, final int startIndex, final double tolerance) {
2864 if (Double.isNaN(valueToFind)) {
2865 return indexOfNaN(array, startIndex);
2866 }
2867 if (isEmpty(array)) {
2868 return INDEX_NOT_FOUND;
2869 }
2870 final double min = valueToFind - tolerance;
2871 final double max = valueToFind + tolerance;
2872 for (int i = max0(startIndex); i < array.length; i++) {
2873 if (array[i] >= min && array[i] <= max) {
2874 return i;
2875 }
2876 }
2877 return INDEX_NOT_FOUND;
2878 }
2879
2880 /**
2881 * Finds the index of the given value in the array.
2882 * <p>
2883 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2884 * </p>
2885 *
2886 * @param array the array to search for the object, may be {@code null}.
2887 * @param valueToFind the value to find.
2888 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2889 */
2890 public static int indexOf(final float[] array, final float valueToFind) {
2891 return indexOf(array, valueToFind, 0);
2892 }
2893
2894 /**
2895 * Finds the index of the given value in the array starting at the given index.
2896 * <p>
2897 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2898 * </p>
2899 * <p>
2900 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2901 * </p>
2902 *
2903 * @param array the array to search for the object, may be {@code null}.
2904 * @param valueToFind the value to find.
2905 * @param startIndex the index to start searching.
2906 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2907 */
2908 public static int indexOf(final float[] array, final float valueToFind, final int startIndex) {
2909 if (isEmpty(array)) {
2910 return INDEX_NOT_FOUND;
2911 }
2912 final boolean searchNaN = Float.isNaN(valueToFind);
2913 for (int i = max0(startIndex); i < array.length; i++) {
2914 final float element = array[i];
2915 if (valueToFind == element || searchNaN && Float.isNaN(element)) {
2916 return i;
2917 }
2918 }
2919 return INDEX_NOT_FOUND;
2920 }
2921
2922 /**
2923 * Finds the index of the given value in the array.
2924 * <p>
2925 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2926 * </p>
2927 *
2928 * @param array the array to search for the object, may be {@code null}.
2929 * @param valueToFind the value to find.
2930 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2931 */
2932 public static int indexOf(final int[] array, final int valueToFind) {
2933 return indexOf(array, valueToFind, 0);
2934 }
2935
2936 /**
2937 * Finds the index of the given value in the array starting at the given index.
2938 * <p>
2939 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2940 * </p>
2941 * <p>
2942 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2943 * </p>
2944 *
2945 * @param array the array to search for the object, may be {@code null}.
2946 * @param valueToFind the value to find.
2947 * @param startIndex the index to start searching.
2948 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2949 */
2950 public static int indexOf(final int[] array, final int valueToFind, final int startIndex) {
2951 if (isEmpty(array)) {
2952 return INDEX_NOT_FOUND;
2953 }
2954 for (int i = max0(startIndex); i < array.length; i++) {
2955 if (valueToFind == array[i]) {
2956 return i;
2957 }
2958 }
2959 return INDEX_NOT_FOUND;
2960 }
2961
2962 /**
2963 * Finds the index of the given value in the array.
2964 * <p>
2965 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2966 * </p>
2967 *
2968 * @param array the array to search for the object, may be {@code null}.
2969 * @param valueToFind the value to find.
2970 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2971 */
2972 public static int indexOf(final long[] array, final long valueToFind) {
2973 return indexOf(array, valueToFind, 0);
2974 }
2975
2976 /**
2977 * Finds the index of the given value in the array starting at the given index.
2978 * <p>
2979 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
2980 * </p>
2981 * <p>
2982 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
2983 * </p>
2984 *
2985 * @param array the array to search for the object, may be {@code null}.
2986 * @param valueToFind the value to find.
2987 * @param startIndex the index to start searching.
2988 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
2989 */
2990 public static int indexOf(final long[] array, final long valueToFind, final int startIndex) {
2991 if (isEmpty(array)) {
2992 return INDEX_NOT_FOUND;
2993 }
2994 for (int i = max0(startIndex); i < array.length; i++) {
2995 if (valueToFind == array[i]) {
2996 return i;
2997 }
2998 }
2999 return INDEX_NOT_FOUND;
3000 }
3001
3002 /**
3003 * Finds the index of the given object in the array.
3004 * <p>
3005 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3006 * </p>
3007 *
3008 * @param array the array to search for the object, may be {@code null}.
3009 * @param objectToFind the object to find, may be {@code null}.
3010 * @return the index of the object within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
3011 */
3012 public static int indexOf(final Object[] array, final Object objectToFind) {
3013 return indexOf(array, objectToFind, 0);
3014 }
3015
3016 /**
3017 * Finds the index of the given object in the array starting at the given index.
3018 * <p>
3019 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3020 * </p>
3021 * <p>
3022 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
3023 * </p>
3024 *
3025 * @param array the array to search for the object, may be {@code null}.
3026 * @param objectToFind the object to find, may be {@code null}.
3027 * @param startIndex the index to start searching.
3028 * @return the index of the object within the array starting at the index, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
3029 */
3030 public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
3031 if (isEmpty(array)) {
3032 return INDEX_NOT_FOUND;
3033 }
3034 startIndex = max0(startIndex);
3035 if (objectToFind == null) {
3036 for (int i = startIndex; i < array.length; i++) {
3037 if (array[i] == null) {
3038 return i;
3039 }
3040 }
3041 } else {
3042 for (int i = startIndex; i < array.length; i++) {
3043 if (objectToFind.equals(array[i])) {
3044 return i;
3045 }
3046 }
3047 }
3048 return INDEX_NOT_FOUND;
3049 }
3050
3051 /**
3052 * Finds the index of the given value in the array.
3053 * <p>
3054 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3055 * </p>
3056 *
3057 * @param array the array to search for the object, may be {@code null}
3058 * @param valueToFind the value to find.
3059 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
3060 */
3061 public static int indexOf(final short[] array, final short valueToFind) {
3062 return indexOf(array, valueToFind, 0);
3063 }
3064
3065 /**
3066 * Finds the index of the given value in the array starting at the given index.
3067 * <p>
3068 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
3069 * </p>
3070 * <p>
3071 * A negative startIndex is treated as zero. A startIndex larger than the array length will return {@link #INDEX_NOT_FOUND} ({@code -1}).
3072 * </p>
3073 *
3074 * @param array the array to search for the object, may be {@code null}.
3075 * @param valueToFind the value to find.
3076 * @param startIndex the index to start searching.
3077 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
3078 */
3079 public static int indexOf(final short[] array, final short valueToFind, final int startIndex) {
3080 if (isEmpty(array)) {
3081 return INDEX_NOT_FOUND;
3082 }
3083 for (int i = max0(startIndex); i < array.length; i++) {
3084 if (valueToFind == array[i]) {
3085 return i;
3086 }
3087 }
3088 return INDEX_NOT_FOUND;
3089 }
3090
3091 /**
3092 * Finds the index of the NaN value in a double array.
3093 * @param array the array to search for NaN, may be {@code null}.
3094 * @param startIndex the index to start searching.
3095 * @return the index of the NaN value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
3096 */
3097 private static int indexOfNaN(final double[] array, final int startIndex) {
3098 if (isEmpty(array)) {
3099 return INDEX_NOT_FOUND;
3100 }
3101 for (int i = max0(startIndex); i < array.length; i++) {
3102 if (Double.isNaN(array[i])) {
3103 return i;
3104 }
3105 }
3106 return INDEX_NOT_FOUND;
3107 }
3108
3109 /**
3110 * Inserts elements into an array at the given index (starting from zero).
3111 *
3112 * <p>
3113 * When an array is returned, it is always a new array.
3114 * </p>
3115 *
3116 * <pre>
3117 * ArrayUtils.insert(index, null, null) = null
3118 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3119 * ArrayUtils.insert(index, null, values) = null
3120 * </pre>
3121 *
3122 * @param index the position within {@code array} to insert the new values.
3123 * @param array the array to insert the values into, may be {@code null}.
3124 * @param values the new values to insert, may be {@code null}.
3125 * @return The new array or {@code null} if the given array is {@code null}.
3126 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3127 * @since 3.6
3128 */
3129 public static boolean[] insert(final int index, final boolean[] array, final boolean... values) {
3130 if (array == null) {
3131 return null;
3132 }
3133 if (isEmpty(values)) {
3134 return clone(array);
3135 }
3136 if (index < 0 || index > array.length) {
3137 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3138 }
3139 final boolean[] result = new boolean[array.length + values.length];
3140 System.arraycopy(values, 0, result, index, values.length);
3141 if (index > 0) {
3142 System.arraycopy(array, 0, result, 0, index);
3143 }
3144 if (index < array.length) {
3145 System.arraycopy(array, index, result, index + values.length, array.length - index);
3146 }
3147 return result;
3148 }
3149
3150 /**
3151 * Inserts elements into an array at the given index (starting from zero).
3152 *
3153 * <p>
3154 * When an array is returned, it is always a new array.
3155 * </p>
3156 *
3157 * <pre>
3158 * ArrayUtils.insert(index, null, null) = null
3159 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3160 * ArrayUtils.insert(index, null, values) = null
3161 * </pre>
3162 *
3163 * @param index the position within {@code array} to insert the new values.
3164 * @param array the array to insert the values into, may be {@code null}.
3165 * @param values the new values to insert, may be {@code null}.
3166 * @return The new array or {@code null} if the given array is {@code null}.
3167 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3168 * @since 3.6
3169 */
3170 public static byte[] insert(final int index, final byte[] array, final byte... values) {
3171 if (array == null) {
3172 return null;
3173 }
3174 if (isEmpty(values)) {
3175 return clone(array);
3176 }
3177 if (index < 0 || index > array.length) {
3178 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3179 }
3180 final byte[] result = new byte[array.length + values.length];
3181 System.arraycopy(values, 0, result, index, values.length);
3182 if (index > 0) {
3183 System.arraycopy(array, 0, result, 0, index);
3184 }
3185 if (index < array.length) {
3186 System.arraycopy(array, index, result, index + values.length, array.length - index);
3187 }
3188 return result;
3189 }
3190
3191 /**
3192 * Inserts elements into an array at the given index (starting from zero).
3193 *
3194 * <p>
3195 * When an array is returned, it is always a new array.
3196 * </p>
3197 *
3198 * <pre>
3199 * ArrayUtils.insert(index, null, null) = null
3200 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3201 * ArrayUtils.insert(index, null, values) = null
3202 * </pre>
3203 *
3204 * @param index the position within {@code array} to insert the new values.
3205 * @param array the array to insert the values into, may be {@code null}.
3206 * @param values the new values to insert, may be {@code null}.
3207 * @return The new array or {@code null} if the given array is {@code null}.
3208 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3209 * @since 3.6
3210 */
3211 public static char[] insert(final int index, final char[] array, final char... values) {
3212 if (array == null) {
3213 return null;
3214 }
3215 if (isEmpty(values)) {
3216 return clone(array);
3217 }
3218 if (index < 0 || index > array.length) {
3219 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3220 }
3221 final char[] result = new char[array.length + values.length];
3222 System.arraycopy(values, 0, result, index, values.length);
3223 if (index > 0) {
3224 System.arraycopy(array, 0, result, 0, index);
3225 }
3226 if (index < array.length) {
3227 System.arraycopy(array, index, result, index + values.length, array.length - index);
3228 }
3229 return result;
3230 }
3231
3232 /**
3233 * Inserts elements into an array at the given index (starting from zero).
3234 *
3235 * <p>
3236 * When an array is returned, it is always a new array.
3237 * </p>
3238 *
3239 * <pre>
3240 * ArrayUtils.insert(index, null, null) = null
3241 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3242 * ArrayUtils.insert(index, null, values) = null
3243 * </pre>
3244 *
3245 * @param index the position within {@code array} to insert the new values.
3246 * @param array the array to insert the values into, may be {@code null}.
3247 * @param values the new values to insert, may be {@code null}.
3248 * @return The new array or {@code null} if the given array is {@code null}.
3249 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3250 * @since 3.6
3251 */
3252 public static double[] insert(final int index, final double[] array, final double... values) {
3253 if (array == null) {
3254 return null;
3255 }
3256 if (isEmpty(values)) {
3257 return clone(array);
3258 }
3259 if (index < 0 || index > array.length) {
3260 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3261 }
3262 final double[] result = new double[array.length + values.length];
3263 System.arraycopy(values, 0, result, index, values.length);
3264 if (index > 0) {
3265 System.arraycopy(array, 0, result, 0, index);
3266 }
3267 if (index < array.length) {
3268 System.arraycopy(array, index, result, index + values.length, array.length - index);
3269 }
3270 return result;
3271 }
3272
3273 /**
3274 * Inserts elements into an array at the given index (starting from zero).
3275 *
3276 * <p>
3277 * When an array is returned, it is always a new array.
3278 * </p>
3279 *
3280 * <pre>
3281 * ArrayUtils.insert(index, null, null) = null
3282 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3283 * ArrayUtils.insert(index, null, values) = null
3284 * </pre>
3285 *
3286 * @param index the position within {@code array} to insert the new values.
3287 * @param array the array to insert the values into, may be {@code null}.
3288 * @param values the new values to insert, may be {@code null}.
3289 * @return The new array or {@code null} if the given array is {@code null}.
3290 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3291 * @since 3.6
3292 */
3293 public static float[] insert(final int index, final float[] array, final float... values) {
3294 if (array == null) {
3295 return null;
3296 }
3297 if (isEmpty(values)) {
3298 return clone(array);
3299 }
3300 if (index < 0 || index > array.length) {
3301 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3302 }
3303 final float[] result = new float[array.length + values.length];
3304 System.arraycopy(values, 0, result, index, values.length);
3305 if (index > 0) {
3306 System.arraycopy(array, 0, result, 0, index);
3307 }
3308 if (index < array.length) {
3309 System.arraycopy(array, index, result, index + values.length, array.length - index);
3310 }
3311 return result;
3312 }
3313
3314 /**
3315 * Inserts elements into an array at the given index (starting from zero).
3316 *
3317 * <p>
3318 * When an array is returned, it is always a new array.
3319 * </p>
3320 *
3321 * <pre>
3322 * ArrayUtils.insert(index, null, null) = null
3323 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3324 * ArrayUtils.insert(index, null, values) = null
3325 * </pre>
3326 *
3327 * @param index the position within {@code array} to insert the new values.
3328 * @param array the array to insert the values into, may be {@code null}.
3329 * @param values the new values to insert, may be {@code null}.
3330 * @return The new array or {@code null} if the given array is {@code null}.
3331 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3332 * @since 3.6
3333 */
3334 public static int[] insert(final int index, final int[] array, final int... values) {
3335 if (array == null) {
3336 return null;
3337 }
3338 if (isEmpty(values)) {
3339 return clone(array);
3340 }
3341 if (index < 0 || index > array.length) {
3342 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3343 }
3344 final int[] result = new int[array.length + values.length];
3345 System.arraycopy(values, 0, result, index, values.length);
3346 if (index > 0) {
3347 System.arraycopy(array, 0, result, 0, index);
3348 }
3349 if (index < array.length) {
3350 System.arraycopy(array, index, result, index + values.length, array.length - index);
3351 }
3352 return result;
3353 }
3354
3355 /**
3356 * Inserts elements into an array at the given index (starting from zero).
3357 *
3358 * <p>
3359 * When an array is returned, it is always a new array.
3360 * </p>
3361 *
3362 * <pre>
3363 * ArrayUtils.insert(index, null, null) = null
3364 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3365 * ArrayUtils.insert(index, null, values) = null
3366 * </pre>
3367 *
3368 * @param index the position within {@code array} to insert the new values.
3369 * @param array the array to insert the values into, may be {@code null}.
3370 * @param values the new values to insert, may be {@code null}.
3371 * @return The new array or {@code null} if the given array is {@code null}.
3372 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3373 * @since 3.6
3374 */
3375 public static long[] insert(final int index, final long[] array, final long... values) {
3376 if (array == null) {
3377 return null;
3378 }
3379 if (isEmpty(values)) {
3380 return clone(array);
3381 }
3382 if (index < 0 || index > array.length) {
3383 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3384 }
3385 final long[] result = new long[array.length + values.length];
3386 System.arraycopy(values, 0, result, index, values.length);
3387 if (index > 0) {
3388 System.arraycopy(array, 0, result, 0, index);
3389 }
3390 if (index < array.length) {
3391 System.arraycopy(array, index, result, index + values.length, array.length - index);
3392 }
3393 return result;
3394 }
3395
3396 /**
3397 * Inserts elements into an array at the given index (starting from zero).
3398 *
3399 * <p>
3400 * When an array is returned, it is always a new array.
3401 * </p>
3402 *
3403 * <pre>
3404 * ArrayUtils.insert(index, null, null) = null
3405 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3406 * ArrayUtils.insert(index, null, values) = null
3407 * </pre>
3408 *
3409 * @param index the position within {@code array} to insert the new values.
3410 * @param array the array to insert the values into, may be {@code null}.
3411 * @param values the new values to insert, may be {@code null}.
3412 * @return The new array or {@code null} if the given array is {@code null}.
3413 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3414 * @since 3.6
3415 */
3416 public static short[] insert(final int index, final short[] array, final short... values) {
3417 if (array == null) {
3418 return null;
3419 }
3420 if (isEmpty(values)) {
3421 return clone(array);
3422 }
3423 if (index < 0 || index > array.length) {
3424 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3425 }
3426 final short[] result = new short[array.length + values.length];
3427 System.arraycopy(values, 0, result, index, values.length);
3428 if (index > 0) {
3429 System.arraycopy(array, 0, result, 0, index);
3430 }
3431 if (index < array.length) {
3432 System.arraycopy(array, index, result, index + values.length, array.length - index);
3433 }
3434 return result;
3435 }
3436
3437 /**
3438 * Inserts elements into an array at the given index (starting from zero).
3439 *
3440 * <p>
3441 * When an array is returned, it is always a new array.
3442 * </p>
3443 *
3444 * <pre>
3445 * ArrayUtils.insert(index, null, null) = null
3446 * ArrayUtils.insert(index, array, null) = cloned copy of 'array'
3447 * ArrayUtils.insert(index, null, values) = null
3448 * </pre>
3449 *
3450 * @param <T> The type of elements in {@code array} and {@code values}.
3451 * @param index the position within {@code array} to insert the new values.
3452 * @param array the array to insert the values into, may be {@code null}.
3453 * @param values the new values to insert, may be {@code null}.
3454 * @return The new array or {@code null} if the given array is {@code null}.
3455 * @throws IndexOutOfBoundsException if {@code array} is provided and either {@code index < 0} or {@code index > array.length}.
3456 * @since 3.6
3457 */
3458 @SafeVarargs
3459 public static <T> T[] insert(final int index, final T[] array, final T... values) {
3460 /*
3461 * Note on use of @SafeVarargs:
3462 *
3463 * By returning null when 'array' is null, we avoid returning the vararg
3464 * array to the caller. We also avoid relying on the type of the vararg
3465 * array, by inspecting the component type of 'array'.
3466 */
3467 if (array == null) {
3468 return null;
3469 }
3470 if (isEmpty(values)) {
3471 return clone(array);
3472 }
3473 if (index < 0 || index > array.length) {
3474 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + array.length);
3475 }
3476 final Class<T> type = getComponentType(array);
3477 final int length = array.length + values.length;
3478 final T[] result = newInstance(type, length);
3479 System.arraycopy(values, 0, result, index, values.length);
3480 if (index > 0) {
3481 System.arraycopy(array, 0, result, 0, index);
3482 }
3483 if (index < array.length) {
3484 System.arraycopy(array, index, result, index + values.length, array.length - index);
3485 }
3486 return result;
3487 }
3488
3489 /**
3490 * Checks if an array is empty or {@code null}.
3491 *
3492 * @param array the array to test.
3493 * @return {@code true} if the array is empty or {@code null}.
3494 */
3495 private static boolean isArrayEmpty(final Object array) {
3496 return getLength(array) == 0;
3497 }
3498
3499 /**
3500 * Tests whether a given array can safely be accessed at the given index.
3501 *
3502 * <pre>
3503 * ArrayUtils.isArrayIndexValid(null, 0) = false
3504 * ArrayUtils.isArrayIndexValid([], 0) = false
3505 * ArrayUtils.isArrayIndexValid(["a"], 0) = true
3506 * </pre>
3507 *
3508 * @param <T> the component type of the array.
3509 * @param array the array to inspect, may be {@code null}.
3510 * @param index the index of the array to be inspected.
3511 * @return Whether the given index is safely-accessible in the given array.
3512 * @since 3.8
3513 */
3514 public static <T> boolean isArrayIndexValid(final T[] array, final int index) {
3515 return index >= 0 && getLength(array) > index;
3516 }
3517
3518 /**
3519 * Tests whether an array of primitive booleans is empty or {@code null}.
3520 *
3521 * @param array the array to test.
3522 * @return {@code true} if the array is empty or {@code null}.
3523 * @since 2.1
3524 */
3525 public static boolean isEmpty(final boolean[] array) {
3526 return isArrayEmpty(array);
3527 }
3528
3529 /**
3530 * Tests whether an array of primitive bytes is empty or {@code null}.
3531 *
3532 * @param array the array to test.
3533 * @return {@code true} if the array is empty or {@code null}.
3534 * @since 2.1
3535 */
3536 public static boolean isEmpty(final byte[] array) {
3537 return isArrayEmpty(array);
3538 }
3539
3540 /**
3541 * Tests whether an array of primitive chars is empty or {@code null}.
3542 *
3543 * @param array the array to test.
3544 * @return {@code true} if the array is empty or {@code null}.
3545 * @since 2.1
3546 */
3547 public static boolean isEmpty(final char[] array) {
3548 return isArrayEmpty(array);
3549 }
3550
3551 /**
3552 * Tests whether an array of primitive doubles is empty or {@code null}.
3553 *
3554 * @param array the array to test.
3555 * @return {@code true} if the array is empty or {@code null}.
3556 * @since 2.1
3557 */
3558 public static boolean isEmpty(final double[] array) {
3559 return isArrayEmpty(array);
3560 }
3561
3562 /**
3563 * Tests whether an array of primitive floats is empty or {@code null}.
3564 *
3565 * @param array the array to test.
3566 * @return {@code true} if the array is empty or {@code null}.
3567 * @since 2.1
3568 */
3569 public static boolean isEmpty(final float[] array) {
3570 return isArrayEmpty(array);
3571 }
3572
3573 /**
3574 * Tests whether an array of primitive ints is empty or {@code null}.
3575 *
3576 * @param array the array to test.
3577 * @return {@code true} if the array is empty or {@code null}.
3578 * @since 2.1
3579 */
3580 public static boolean isEmpty(final int[] array) {
3581 return isArrayEmpty(array);
3582 }
3583
3584 /**
3585 * Tests whether an array of primitive longs is empty or {@code null}.
3586 *
3587 * @param array the array to test.
3588 * @return {@code true} if the array is empty or {@code null}.
3589 * @since 2.1
3590 */
3591 public static boolean isEmpty(final long[] array) {
3592 return isArrayEmpty(array);
3593 }
3594
3595 /**
3596 * Tests whether an array of Objects is empty or {@code null}.
3597 *
3598 * @param array the array to test.
3599 * @return {@code true} if the array is empty or {@code null}.
3600 * @since 2.1
3601 */
3602 public static boolean isEmpty(final Object[] array) {
3603 return isArrayEmpty(array);
3604 }
3605
3606 /**
3607 * Tests whether an array of primitive shorts is empty or {@code null}.
3608 *
3609 * @param array the array to test.
3610 * @return {@code true} if the array is empty or {@code null}.
3611 * @since 2.1
3612 */
3613 public static boolean isEmpty(final short[] array) {
3614 return isArrayEmpty(array);
3615 }
3616
3617 /**
3618 * Tests whether two arrays have equal content, using equals(), handling multidimensional arrays
3619 * correctly.
3620 * <p>
3621 * Multi-dimensional primitive arrays are also handled correctly by this method.
3622 * </p>
3623 *
3624 * @param array1 the left-hand side array to compare, may be {@code null}.
3625 * @param array2 the right-hand side array to compare, may be {@code null}.
3626 * @return {@code true} if the arrays are equal.
3627 * @deprecated Replaced by {@code java.util.Objects.deepEquals(Object, Object)} and will be
3628 * removed from future releases.
3629 */
3630 @Deprecated
3631 public static boolean isEquals(final Object array1, final Object array2) {
3632 return new EqualsBuilder().append(array1, array2).isEquals();
3633 }
3634
3635 /**
3636 * Tests whether an array of primitive booleans is not empty and not {@code null}.
3637 *
3638 * @param array the array to test.
3639 * @return {@code true} if the array is not empty and not {@code null}.
3640 * @since 2.5
3641 */
3642 public static boolean isNotEmpty(final boolean[] array) {
3643 return !isEmpty(array);
3644 }
3645
3646 /**
3647 * Tests whether an array of primitive bytes is not empty and not {@code null}.
3648 *
3649 * @param array the array to test.
3650 * @return {@code true} if the array is not empty and not {@code null}.
3651 * @since 2.5
3652 */
3653 public static boolean isNotEmpty(final byte[] array) {
3654 return !isEmpty(array);
3655 }
3656
3657 /**
3658 * Tests whether an array of primitive chars is not empty and not {@code null}.
3659 *
3660 * @param array the array to test.
3661 * @return {@code true} if the array is not empty and not {@code null}.
3662 * @since 2.5
3663 */
3664 public static boolean isNotEmpty(final char[] array) {
3665 return !isEmpty(array);
3666 }
3667
3668 /**
3669 * Tests whether an array of primitive doubles is not empty and not {@code null}.
3670 *
3671 * @param array the array to test.
3672 * @return {@code true} if the array is not empty and not {@code null}.
3673 * @since 2.5
3674 */
3675 public static boolean isNotEmpty(final double[] array) {
3676 return !isEmpty(array);
3677 }
3678
3679 /**
3680 * Tests whether an array of primitive floats is not empty and not {@code null}.
3681 *
3682 * @param array the array to test.
3683 * @return {@code true} if the array is not empty and not {@code null}.
3684 * @since 2.5
3685 */
3686 public static boolean isNotEmpty(final float[] array) {
3687 return !isEmpty(array);
3688 }
3689
3690 /**
3691 * Tests whether an array of primitive ints is not empty and not {@code null}.
3692 *
3693 * @param array the array to test.
3694 * @return {@code true} if the array is not empty and not {@code null}.
3695 * @since 2.5
3696 */
3697 public static boolean isNotEmpty(final int[] array) {
3698 return !isEmpty(array);
3699 }
3700
3701 /**
3702 * Tests whether an array of primitive longs is not empty and not {@code null}.
3703 *
3704 * @param array the array to test.
3705 * @return {@code true} if the array is not empty and not {@code null}.
3706 * @since 2.5
3707 */
3708 public static boolean isNotEmpty(final long[] array) {
3709 return !isEmpty(array);
3710 }
3711
3712 /**
3713 * Tests whether an array of primitive shorts is not empty and not {@code null}.
3714 *
3715 * @param array the array to test.
3716 * @return {@code true} if the array is not empty and not {@code null}.
3717 * @since 2.5
3718 */
3719 public static boolean isNotEmpty(final short[] array) {
3720 return !isEmpty(array);
3721 }
3722
3723 /**
3724 * Tests whether an array of Objects is not empty and not {@code null}.
3725 *
3726 * @param <T> the component type of the array
3727 * @param array the array to test.
3728 * @return {@code true} if the array is not empty and not {@code null}.
3729 * @since 2.5
3730 */
3731 public static <T> boolean isNotEmpty(final T[] array) {
3732 return !isEmpty(array);
3733 }
3734
3735 /**
3736 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3737 *
3738 * @param array1 the first array, may be {@code null}.
3739 * @param array2 the second array, may be {@code null}.
3740 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3741 */
3742 public static boolean isSameLength(final boolean[] array1, final boolean[] array2) {
3743 return getLength(array1) == getLength(array2);
3744 }
3745
3746 /**
3747 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3748 *
3749 * @param array1 the first array, may be {@code null}.
3750 * @param array2 the second array, may be {@code null}.
3751 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3752 */
3753 public static boolean isSameLength(final byte[] array1, final byte[] array2) {
3754 return getLength(array1) == getLength(array2);
3755 }
3756
3757 /**
3758 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3759 *
3760 * @param array1 the first array, may be {@code null}.
3761 * @param array2 the second array, may be {@code null}.
3762 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3763 */
3764 public static boolean isSameLength(final char[] array1, final char[] array2) {
3765 return getLength(array1) == getLength(array2);
3766 }
3767
3768 /**
3769 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3770 *
3771 * @param array1 the first array, may be {@code null}.
3772 * @param array2 the second array, may be {@code null}.
3773 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3774 */
3775 public static boolean isSameLength(final double[] array1, final double[] array2) {
3776 return getLength(array1) == getLength(array2);
3777 }
3778
3779 /**
3780 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3781 *
3782 * @param array1 the first array, may be {@code null}.
3783 * @param array2 the second array, may be {@code null}.
3784 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3785 */
3786 public static boolean isSameLength(final float[] array1, final float[] array2) {
3787 return getLength(array1) == getLength(array2);
3788 }
3789
3790 /**
3791 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3792 *
3793 * @param array1 the first array, may be {@code null}.
3794 * @param array2 the second array, may be {@code null}.
3795 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3796 */
3797 public static boolean isSameLength(final int[] array1, final int[] array2) {
3798 return getLength(array1) == getLength(array2);
3799 }
3800
3801 /**
3802 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3803 *
3804 * @param array1 the first array, may be {@code null}.
3805 * @param array2 the second array, may be {@code null}.
3806 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3807 */
3808 public static boolean isSameLength(final long[] array1, final long[] array2) {
3809 return getLength(array1) == getLength(array2);
3810 }
3811
3812 /**
3813 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3814 * <p>
3815 * Any multi-dimensional aspects of the arrays are ignored.
3816 * </p>
3817 *
3818 * @param array1 the first array, may be {@code null}.
3819 * @param array2 the second array, may be {@code null}.
3820 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3821 * @since 3.11
3822 */
3823 public static boolean isSameLength(final Object array1, final Object array2) {
3824 return getLength(array1) == getLength(array2);
3825 }
3826
3827 /**
3828 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3829 * <p>
3830 * Any multi-dimensional aspects of the arrays are ignored.
3831 * </p>
3832 *
3833 * @param array1 the first array, may be {@code null}.
3834 * @param array2 the second array, may be {@code null}.
3835 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3836 */
3837 public static boolean isSameLength(final Object[] array1, final Object[] array2) {
3838 return getLength(array1) == getLength(array2);
3839 }
3840
3841 /**
3842 * Tests whether two arrays are the same length, treating {@code null} arrays as length {@code 0}.
3843 *
3844 * @param array1 the first array, may be {@code null}.
3845 * @param array2 the second array, may be {@code null}.
3846 * @return {@code true} if length of arrays matches, treating {@code null} as an empty array.
3847 */
3848 public static boolean isSameLength(final short[] array1, final short[] array2) {
3849 return getLength(array1) == getLength(array2);
3850 }
3851
3852 /**
3853 * Tests whether two arrays are the same type taking into account multidimensional arrays.
3854 *
3855 * @param array1 the first array, must not be {@code null}.
3856 * @param array2 the second array, must not be {@code null}.
3857 * @return {@code true} if type of arrays matches.
3858 * @throws IllegalArgumentException if either array is {@code null}.
3859 */
3860 public static boolean isSameType(final Object array1, final Object array2) {
3861 if (array1 == null || array2 == null) {
3862 throw new IllegalArgumentException("The Array must not be null");
3863 }
3864 return array1.getClass().getName().equals(array2.getClass().getName());
3865 }
3866
3867 /**
3868 * Tests whether whether the provided array is sorted according to natural ordering ({@code false} before {@code true}).
3869 *
3870 * @param array the array to check.
3871 * @return whether the array is sorted according to natural ordering.
3872 * @since 3.4
3873 */
3874 public static boolean isSorted(final boolean[] array) {
3875 if (getLength(array) < 2) {
3876 return true;
3877 }
3878 boolean previous = array[0];
3879 final int n = array.length;
3880 for (int i = 1; i < n; i++) {
3881 final boolean current = array[i];
3882 if (BooleanUtils.compare(previous, current) > 0) {
3883 return false;
3884 }
3885 previous = current;
3886 }
3887 return true;
3888 }
3889
3890 /**
3891 * Tests whether the provided array is sorted according to natural ordering.
3892 *
3893 * @param array the array to check.
3894 * @return whether the array is sorted according to natural ordering.
3895 * @since 3.4
3896 */
3897 public static boolean isSorted(final byte[] array) {
3898 if (getLength(array) < 2) {
3899 return true;
3900 }
3901 byte previous = array[0];
3902 final int n = array.length;
3903 for (int i = 1; i < n; i++) {
3904 final byte current = array[i];
3905 if (Byte.compare(previous, current) > 0) {
3906 return false;
3907 }
3908 previous = current;
3909 }
3910 return true;
3911 }
3912
3913 /**
3914 * Tests whether the provided array is sorted according to natural ordering.
3915 *
3916 * @param array the array to check.
3917 * @return whether the array is sorted according to natural ordering.
3918 * @since 3.4
3919 */
3920 public static boolean isSorted(final char[] array) {
3921 if (getLength(array) < 2) {
3922 return true;
3923 }
3924 char previous = array[0];
3925 final int n = array.length;
3926 for (int i = 1; i < n; i++) {
3927 final char current = array[i];
3928 if (CharUtils.compare(previous, current) > 0) {
3929 return false;
3930 }
3931 previous = current;
3932 }
3933 return true;
3934 }
3935
3936 /**
3937 * Tests whether the provided array is sorted according to natural ordering.
3938 *
3939 * @param array the array to check.
3940 * @return whether the array is sorted according to natural ordering.
3941 * @since 3.4
3942 */
3943 public static boolean isSorted(final double[] array) {
3944 if (getLength(array) < 2) {
3945 return true;
3946 }
3947 double previous = array[0];
3948 final int n = array.length;
3949 for (int i = 1; i < n; i++) {
3950 final double current = array[i];
3951 if (Double.compare(previous, current) > 0) {
3952 return false;
3953 }
3954 previous = current;
3955 }
3956 return true;
3957 }
3958
3959 /**
3960 * Tests whether the provided array is sorted according to natural ordering.
3961 *
3962 * @param array the array to check.
3963 * @return whether the array is sorted according to natural ordering.
3964 * @since 3.4
3965 */
3966 public static boolean isSorted(final float[] array) {
3967 if (getLength(array) < 2) {
3968 return true;
3969 }
3970 float previous = array[0];
3971 final int n = array.length;
3972 for (int i = 1; i < n; i++) {
3973 final float current = array[i];
3974 if (Float.compare(previous, current) > 0) {
3975 return false;
3976 }
3977 previous = current;
3978 }
3979 return true;
3980 }
3981
3982 /**
3983 * Tests whether the provided array is sorted according to natural ordering.
3984 *
3985 * @param array the array to check.
3986 * @return whether the array is sorted according to natural ordering.
3987 * @since 3.4
3988 */
3989 public static boolean isSorted(final int[] array) {
3990 if (getLength(array) < 2) {
3991 return true;
3992 }
3993 int previous = array[0];
3994 final int n = array.length;
3995 for (int i = 1; i < n; i++) {
3996 final int current = array[i];
3997 if (Integer.compare(previous, current) > 0) {
3998 return false;
3999 }
4000 previous = current;
4001 }
4002 return true;
4003 }
4004
4005 /**
4006 * Tests whether the provided array is sorted according to natural ordering.
4007 *
4008 * @param array the array to check.
4009 * @return whether the array is sorted according to natural ordering.
4010 * @since 3.4
4011 */
4012 public static boolean isSorted(final long[] array) {
4013 if (getLength(array) < 2) {
4014 return true;
4015 }
4016 long previous = array[0];
4017 final int n = array.length;
4018 for (int i = 1; i < n; i++) {
4019 final long current = array[i];
4020 if (Long.compare(previous, current) > 0) {
4021 return false;
4022 }
4023 previous = current;
4024 }
4025 return true;
4026 }
4027
4028 /**
4029 * Tests whether the provided array is sorted according to natural ordering.
4030 *
4031 * @param array the array to check.
4032 * @return whether the array is sorted according to natural ordering.
4033 * @since 3.4
4034 */
4035 public static boolean isSorted(final short[] array) {
4036 if (getLength(array) < 2) {
4037 return true;
4038 }
4039 short previous = array[0];
4040 final int n = array.length;
4041 for (int i = 1; i < n; i++) {
4042 final short current = array[i];
4043 if (Short.compare(previous, current) > 0) {
4044 return false;
4045 }
4046 previous = current;
4047 }
4048 return true;
4049 }
4050
4051 /**
4052 * Tests whether the provided array is sorted according to the class's
4053 * {@code compareTo} method.
4054 *
4055 * @param array the array to check.
4056 * @param <T> the datatype of the array to check, it must implement {@link Comparable}.
4057 * @return whether the array is sorted.
4058 * @since 3.4
4059 */
4060 public static <T extends Comparable<? super T>> boolean isSorted(final T[] array) {
4061 return isSorted(array, Comparable::compareTo);
4062 }
4063
4064 /**
4065 * Tests whether the provided array is sorted according to the provided {@link Comparator}.
4066 *
4067 * @param array the array to check.
4068 * @param comparator the {@link Comparator} to compare over.
4069 * @param <T> the datatype of the array.
4070 * @return whether the array is sorted.
4071 * @throws NullPointerException if {@code comparator} is {@code null}.
4072 * @since 3.4
4073 */
4074 public static <T> boolean isSorted(final T[] array, final Comparator<T> comparator) {
4075 Objects.requireNonNull(comparator, "comparator");
4076 if (getLength(array) < 2) {
4077 return true;
4078 }
4079 T previous = array[0];
4080 final int n = array.length;
4081 for (int i = 1; i < n; i++) {
4082 final T current = array[i];
4083 if (comparator.compare(previous, current) > 0) {
4084 return false;
4085 }
4086 previous = current;
4087 }
4088 return true;
4089 }
4090
4091 /**
4092 * Finds the last index of the given value within the array.
4093 * <p>
4094 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) if {@code null} array input.
4095 * </p>
4096 *
4097 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4098 * @param valueToFind the object to find.
4099 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4100 */
4101 public static int lastIndexOf(final boolean[] array, final boolean valueToFind) {
4102 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4103 }
4104
4105 /**
4106 * Finds the last index of the given value in the array starting at the given index.
4107 * <p>
4108 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4109 * </p>
4110 * <p>
4111 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4112 * </p>
4113 *
4114 * @param array the array to traverse for looking for the object, may be {@code null}.
4115 * @param valueToFind the value to find.
4116 * @param startIndex the start index to traverse backwards from.
4117 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4118 */
4119 public static int lastIndexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
4120 if (isEmpty(array) || startIndex < 0) {
4121 return INDEX_NOT_FOUND;
4122 }
4123 if (startIndex >= array.length) {
4124 startIndex = array.length - 1;
4125 }
4126 for (int i = startIndex; i >= 0; i--) {
4127 if (valueToFind == array[i]) {
4128 return i;
4129 }
4130 }
4131 return INDEX_NOT_FOUND;
4132 }
4133
4134 /**
4135 * Finds the last index of the given value within the array.
4136 * <p>
4137 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4138 * </p>
4139 *
4140 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4141 * @param valueToFind the object to find.
4142 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4143 */
4144 public static int lastIndexOf(final byte[] array, final byte valueToFind) {
4145 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4146 }
4147
4148 /**
4149 * Finds the last index of the given value in the array starting at the given index.
4150 * <p>
4151 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4152 * </p>
4153 * <p>
4154 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4155 * </p>
4156 *
4157 * @param array the array to traverse for looking for the object, may be {@code null}.
4158 * @param valueToFind the value to find.
4159 * @param startIndex the start index to traverse backwards from.
4160 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4161 */
4162 public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) {
4163 if (array == null || startIndex < 0) {
4164 return INDEX_NOT_FOUND;
4165 }
4166 if (startIndex >= array.length) {
4167 startIndex = array.length - 1;
4168 }
4169 for (int i = startIndex; i >= 0; i--) {
4170 if (valueToFind == array[i]) {
4171 return i;
4172 }
4173 }
4174 return INDEX_NOT_FOUND;
4175 }
4176
4177 /**
4178 * Finds the last index of the given value within the array.
4179 * <p>
4180 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4181 * </p>
4182 *
4183 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4184 * @param valueToFind the object to find.
4185 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4186 * @since 2.1
4187 */
4188 public static int lastIndexOf(final char[] array, final char valueToFind) {
4189 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4190 }
4191
4192 /**
4193 * Finds the last index of the given value in the array starting at the given index.
4194 * <p>
4195 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4196 * </p>
4197 * <p>
4198 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4199 * </p>
4200 *
4201 * @param array the array to traverse for looking for the object, may be {@code null}.
4202 * @param valueToFind the value to find.
4203 * @param startIndex the start index to traverse backwards from.
4204 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4205 * @since 2.1
4206 */
4207 public static int lastIndexOf(final char[] array, final char valueToFind, int startIndex) {
4208 if (array == null || startIndex < 0) {
4209 return INDEX_NOT_FOUND;
4210 }
4211 if (startIndex >= array.length) {
4212 startIndex = array.length - 1;
4213 }
4214 for (int i = startIndex; i >= 0; i--) {
4215 if (valueToFind == array[i]) {
4216 return i;
4217 }
4218 }
4219 return INDEX_NOT_FOUND;
4220 }
4221
4222 /**
4223 * Finds the last index of the given value within the array.
4224 * <p>
4225 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4226 * </p>
4227 *
4228 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4229 * @param valueToFind the object to find.
4230 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4231 */
4232 public static int lastIndexOf(final double[] array, final double valueToFind) {
4233 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4234 }
4235
4236 /**
4237 * Finds the last index of the given value within a given tolerance in the array. This method will return the index of the last value which falls between
4238 * the region defined by valueToFind - tolerance and valueToFind + tolerance.
4239 * <p>
4240 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4241 * </p>
4242 *
4243 * @param array the array to search for the object, may be {@code null}.
4244 * @param valueToFind the value to find.
4245 * @param tolerance tolerance of the search.
4246 * @return the index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4247 */
4248 public static int lastIndexOf(final double[] array, final double valueToFind, final double tolerance) {
4249 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
4250 }
4251
4252 /**
4253 * Finds the last index of the given value in the array starting at the given index.
4254 * <p>
4255 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4256 * </p>
4257 * <p>
4258 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4259 * </p>
4260 *
4261 * @param array the array to traverse for looking for the object, may be {@code null}.
4262 * @param valueToFind the value to find.
4263 * @param startIndex the start index to traverse backwards from.
4264 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4265 */
4266 public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) {
4267 if (isEmpty(array) || startIndex < 0) {
4268 return INDEX_NOT_FOUND;
4269 }
4270 if (startIndex >= array.length) {
4271 startIndex = array.length - 1;
4272 }
4273 for (int i = startIndex; i >= 0; i--) {
4274 if (valueToFind == array[i]) {
4275 return i;
4276 }
4277 }
4278 return INDEX_NOT_FOUND;
4279 }
4280
4281 /**
4282 * Finds the last index of the given value in the array starting at the given index. This method will return the index of the last value which falls between
4283 * the region defined by valueToFind - tolerance and valueToFind + tolerance.
4284 * <p>
4285 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4286 * </p>
4287 * <p>
4288 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4289 * </p>
4290 *
4291 * @param array the array to traverse for looking for the object, may be {@code null}.
4292 * @param valueToFind the value to find.
4293 * @param startIndex the start index to traverse backwards from.
4294 * @param tolerance search for value within plus/minus this amount.
4295 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4296 */
4297 public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
4298 if (isEmpty(array) || startIndex < 0) {
4299 return INDEX_NOT_FOUND;
4300 }
4301 if (startIndex >= array.length) {
4302 startIndex = array.length - 1;
4303 }
4304 final double min = valueToFind - tolerance;
4305 final double max = valueToFind + tolerance;
4306 for (int i = startIndex; i >= 0; i--) {
4307 if (array[i] >= min && array[i] <= max) {
4308 return i;
4309 }
4310 }
4311 return INDEX_NOT_FOUND;
4312 }
4313
4314 /**
4315 * Finds the last index of the given value within the array.
4316 * <p>
4317 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4318 * </p>
4319 *
4320 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4321 * @param valueToFind the object to find.
4322 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4323 */
4324 public static int lastIndexOf(final float[] array, final float valueToFind) {
4325 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4326 }
4327
4328 /**
4329 * Finds the last index of the given value in the array starting at the given index.
4330 * <p>
4331 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4332 * </p>
4333 * <p>
4334 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4335 * </p>
4336 *
4337 * @param array the array to traverse for looking for the object, may be {@code null}.
4338 * @param valueToFind the value to find.
4339 * @param startIndex the start index to traverse backwards from.
4340 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4341 */
4342 public static int lastIndexOf(final float[] array, final float valueToFind, int startIndex) {
4343 if (isEmpty(array) || startIndex < 0) {
4344 return INDEX_NOT_FOUND;
4345 }
4346 if (startIndex >= array.length) {
4347 startIndex = array.length - 1;
4348 }
4349 for (int i = startIndex; i >= 0; i--) {
4350 if (valueToFind == array[i]) {
4351 return i;
4352 }
4353 }
4354 return INDEX_NOT_FOUND;
4355 }
4356
4357 /**
4358 * Finds the last index of the given value within the array.
4359 * <p>
4360 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4361 * </p>
4362 *
4363 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4364 * @param valueToFind the object to find.
4365 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4366 */
4367 public static int lastIndexOf(final int[] array, final int valueToFind) {
4368 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4369 }
4370
4371 /**
4372 * Finds the last index of the given value in the array starting at the given index.
4373 * <p>
4374 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4375 * </p>
4376 * <p>
4377 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4378 * </p>
4379 *
4380 * @param array the array to traverse for looking for the object, may be {@code null}.
4381 * @param valueToFind the value to find.
4382 * @param startIndex the start index to traverse backwards from.
4383 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4384 */
4385 public static int lastIndexOf(final int[] array, final int valueToFind, int startIndex) {
4386 if (array == null || startIndex < 0) {
4387 return INDEX_NOT_FOUND;
4388 }
4389 if (startIndex >= array.length) {
4390 startIndex = array.length - 1;
4391 }
4392 for (int i = startIndex; i >= 0; i--) {
4393 if (valueToFind == array[i]) {
4394 return i;
4395 }
4396 }
4397 return INDEX_NOT_FOUND;
4398 }
4399
4400 /**
4401 * Finds the last index of the given value within the array.
4402 * <p>
4403 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4404 * </p>
4405 *
4406 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4407 * @param valueToFind the object to find.
4408 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4409 */
4410 public static int lastIndexOf(final long[] array, final long valueToFind) {
4411 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4412 }
4413
4414 /**
4415 * Finds the last index of the given value in the array starting at the given index.
4416 * <p>
4417 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4418 * </p>
4419 * <p>
4420 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4421 * </p>
4422 *
4423 * @param array the array to traverse for looking for the object, may be {@code null}.
4424 * @param valueToFind the value to find.
4425 * @param startIndex the start index to traverse backwards from.
4426 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4427 */
4428 public static int lastIndexOf(final long[] array, final long valueToFind, int startIndex) {
4429 if (array == null || startIndex < 0) {
4430 return INDEX_NOT_FOUND;
4431 }
4432 if (startIndex >= array.length) {
4433 startIndex = array.length - 1;
4434 }
4435 for (int i = startIndex; i >= 0; i--) {
4436 if (valueToFind == array[i]) {
4437 return i;
4438 }
4439 }
4440 return INDEX_NOT_FOUND;
4441 }
4442
4443 /**
4444 * Finds the last index of the given object within the array.
4445 * <p>
4446 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4447 * </p>
4448 *
4449 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4450 * @param objectToFind the object to find, may be {@code null}.
4451 * @return the last index of the object within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4452 */
4453 public static int lastIndexOf(final Object[] array, final Object objectToFind) {
4454 return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
4455 }
4456
4457 /**
4458 * Finds the last index of the given object in the array starting at the given index.
4459 * <p>
4460 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4461 * </p>
4462 * <p>
4463 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4464 * </p>
4465 *
4466 * @param array the array to traverse for looking for the object, may be {@code null}.
4467 * @param objectToFind the object to find, may be {@code null}.
4468 * @param startIndex the start index to traverse backwards from.
4469 * @return the last index of the object within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4470 */
4471 public static int lastIndexOf(final Object[] array, final Object objectToFind, int startIndex) {
4472 if (array == null || startIndex < 0) {
4473 return INDEX_NOT_FOUND;
4474 }
4475 if (startIndex >= array.length) {
4476 startIndex = array.length - 1;
4477 }
4478 if (objectToFind == null) {
4479 for (int i = startIndex; i >= 0; i--) {
4480 if (array[i] == null) {
4481 return i;
4482 }
4483 }
4484 } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
4485 for (int i = startIndex; i >= 0; i--) {
4486 if (objectToFind.equals(array[i])) {
4487 return i;
4488 }
4489 }
4490 }
4491 return INDEX_NOT_FOUND;
4492 }
4493
4494 /**
4495 * Finds the last index of the given value within the array.
4496 * <p>
4497 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4498 * </p>
4499 *
4500 * @param array the array to traverse backwards looking for the object, may be {@code null}.
4501 * @param valueToFind the object to find.
4502 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4503 */
4504 public static int lastIndexOf(final short[] array, final short valueToFind) {
4505 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
4506 }
4507
4508 /**
4509 * Finds the last index of the given value in the array starting at the given index.
4510 * <p>
4511 * This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.
4512 * </p>
4513 * <p>
4514 * A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the array length will search from the end of the array.
4515 * </p>
4516 *
4517 * @param array the array to traverse for looking for the object, may be {@code null}.
4518 * @param valueToFind the value to find.
4519 * @param startIndex the start index to traverse backwards from.
4520 * @return the last index of the value within the array, {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input.
4521 */
4522 public static int lastIndexOf(final short[] array, final short valueToFind, int startIndex) {
4523 if (array == null || startIndex < 0) {
4524 return INDEX_NOT_FOUND;
4525 }
4526 if (startIndex >= array.length) {
4527 startIndex = array.length - 1;
4528 }
4529 for (int i = startIndex; i >= 0; i--) {
4530 if (valueToFind == array[i]) {
4531 return i;
4532 }
4533 }
4534 return INDEX_NOT_FOUND;
4535 }
4536
4537 /**
4538 * Maps elements from an array into elements of a new array of a given type, while mapping old elements to new elements.
4539 *
4540 * @param <T> The input array type.
4541 * @param <R> The output array type.
4542 * @param <E> The type of exceptions thrown when the mapper function fails.
4543 * @param array The input array.
4544 * @param componentType the component type of the result array.
4545 * @param mapper a non-interfering, stateless function to apply to each element.
4546 * @return a new array.
4547 * @throws E Thrown when the mapper function fails.
4548 */
4549 private static <T, R, E extends Throwable> R[] map(final T[] array, final Class<R> componentType, final FailableFunction<? super T, ? extends R, E> mapper)
4550 throws E {
4551 return ArrayFill.fill(newInstance(componentType, array.length), i -> mapper.apply(array[i]));
4552 }
4553
4554 private static int max0(final int other) {
4555 return Math.max(0, other);
4556 }
4557
4558 /**
4559 * Delegates to {@link Array#newInstance(Class,int)} using generics.
4560 *
4561 * @param <T> The array type.
4562 * @param componentType The array class.
4563 * @param length the array length
4564 * @return The new array.
4565 * @throws NullPointerException if the specified {@code componentType} parameter is null.
4566 * @since 3.13.0
4567 */
4568 @SuppressWarnings("unchecked") // OK, because array and values are of type T
4569 public static <T> T[] newInstance(final Class<T> componentType, final int length) {
4570 return (T[]) Array.newInstance(componentType, length);
4571 }
4572
4573 /**
4574 * Defensive programming technique to change a {@code null}
4575 * reference to an empty one.
4576 * <p>
4577 * This method returns a default array for a {@code null} input array.
4578 * </p>
4579 * <p>
4580 * As a memory optimizing technique an empty array passed in will be overridden with
4581 * the empty {@code public static} references in this class.
4582 * </p>
4583 *
4584 * @param <T> The array type.
4585 * @param array the array to check for {@code null} or empty
4586 * @param defaultArray A default array, usually empty.
4587 * @return the same array, or defaultArray if {@code null} or empty input.
4588 * @since 3.15.0
4589 */
4590 public static <T> T[] nullTo(final T[] array, final T[] defaultArray) {
4591 return isEmpty(array) ? defaultArray : array;
4592 }
4593
4594 /**
4595 * Defensive programming technique to change a {@code null}
4596 * reference to an empty one.
4597 * <p>
4598 * This method returns an empty array for a {@code null} input array.
4599 * </p>
4600 * <p>
4601 * As a memory optimizing technique an empty array passed in will be overridden with
4602 * the empty {@code public static} references in this class.
4603 * </p>
4604 *
4605 * @param array the array to check for {@code null} or empty.
4606 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4607 * @since 2.5
4608 */
4609 public static boolean[] nullToEmpty(final boolean[] array) {
4610 return isEmpty(array) ? EMPTY_BOOLEAN_ARRAY : array;
4611 }
4612
4613 /**
4614 * Defensive programming technique to change a {@code null}
4615 * reference to an empty one.
4616 * <p>
4617 * This method returns an empty array for a {@code null} input array.
4618 * </p>
4619 * <p>
4620 * As a memory optimizing technique an empty array passed in will be overridden with
4621 * the empty {@code public static} references in this class.
4622 * </p>
4623 *
4624 * @param array the array to check for {@code null} or empty.
4625 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4626 * @since 2.5
4627 */
4628 public static Boolean[] nullToEmpty(final Boolean[] array) {
4629 return nullTo(array, EMPTY_BOOLEAN_OBJECT_ARRAY);
4630 }
4631
4632 /**
4633 * Defensive programming technique to change a {@code null}
4634 * reference to an empty one.
4635 * <p>
4636 * This method returns an empty array for a {@code null} input array.
4637 * </p>
4638 * <p>
4639 * As a memory optimizing technique an empty array passed in will be overridden with
4640 * the empty {@code public static} references in this class.
4641 * </p>
4642 *
4643 * @param array the array to check for {@code null} or empty.
4644 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4645 * @since 2.5
4646 */
4647 public static byte[] nullToEmpty(final byte[] array) {
4648 return isEmpty(array) ? EMPTY_BYTE_ARRAY : array;
4649 }
4650
4651 /**
4652 * Defensive programming technique to change a {@code null}
4653 * reference to an empty one.
4654 * <p>
4655 * This method returns an empty array for a {@code null} input array.
4656 * </p>
4657 * <p>
4658 * As a memory optimizing technique an empty array passed in will be overridden with
4659 * the empty {@code public static} references in this class.
4660 * </p>
4661 *
4662 * @param array the array to check for {@code null} or empty.
4663 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4664 * @since 2.5
4665 */
4666 public static Byte[] nullToEmpty(final Byte[] array) {
4667 return nullTo(array, EMPTY_BYTE_OBJECT_ARRAY);
4668 }
4669
4670 /**
4671 * Defensive programming technique to change a {@code null}
4672 * reference to an empty one.
4673 * <p>
4674 * This method returns an empty array for a {@code null} input array.
4675 * </p>
4676 * <p>
4677 * As a memory optimizing technique an empty array passed in will be overridden with
4678 * the empty {@code public static} references in this class.
4679 * </p>
4680 *
4681 * @param array the array to check for {@code null} or empty.
4682 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4683 * @since 2.5
4684 */
4685 public static char[] nullToEmpty(final char[] array) {
4686 return isEmpty(array) ? EMPTY_CHAR_ARRAY : array;
4687 }
4688
4689 /**
4690 * Defensive programming technique to change a {@code null}
4691 * reference to an empty one.
4692 * <p>
4693 * This method returns an empty array for a {@code null} input array.
4694 * </p>
4695 * <p>
4696 * As a memory optimizing technique an empty array passed in will be overridden with
4697 * the empty {@code public static} references in this class.
4698 * </p>
4699 *
4700 * @param array the array to check for {@code null} or empty.
4701 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4702 * @since 2.5
4703 */
4704 public static Character[] nullToEmpty(final Character[] array) {
4705 return nullTo(array, EMPTY_CHARACTER_OBJECT_ARRAY);
4706 }
4707
4708 /**
4709 * Defensive programming technique to change a {@code null}
4710 * reference to an empty one.
4711 * <p>
4712 * This method returns an empty array for a {@code null} input array.
4713 * </p>
4714 * <p>
4715 * As a memory optimizing technique an empty array passed in will be overridden with
4716 * the empty {@code public static} references in this class.
4717 * </p>
4718 *
4719 * @param array the array to check for {@code null} or empty.
4720 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4721 * @since 3.2
4722 */
4723 public static Class<?>[] nullToEmpty(final Class<?>[] array) {
4724 return nullTo(array, EMPTY_CLASS_ARRAY);
4725 }
4726
4727 /**
4728 * Defensive programming technique to change a {@code null}
4729 * reference to an empty one.
4730 * <p>
4731 * This method returns an empty array for a {@code null} input array.
4732 * </p>
4733 * <p>
4734 * As a memory optimizing technique an empty array passed in will be overridden with
4735 * the empty {@code public static} references in this class.
4736 * </p>
4737 *
4738 * @param array the array to check for {@code null} or empty.
4739 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4740 * @since 2.5
4741 */
4742 public static double[] nullToEmpty(final double[] array) {
4743 return isEmpty(array) ? EMPTY_DOUBLE_ARRAY : array;
4744 }
4745
4746 /**
4747 * Defensive programming technique to change a {@code null}
4748 * reference to an empty one.
4749 * <p>
4750 * This method returns an empty array for a {@code null} input array.
4751 * </p>
4752 * <p>
4753 * As a memory optimizing technique an empty array passed in will be overridden with
4754 * the empty {@code public static} references in this class.
4755 * </p>
4756 *
4757 * @param array the array to check for {@code null} or empty.
4758 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4759 * @since 2.5
4760 */
4761 public static Double[] nullToEmpty(final Double[] array) {
4762 return nullTo(array, EMPTY_DOUBLE_OBJECT_ARRAY);
4763 }
4764
4765 /**
4766 * Defensive programming technique to change a {@code null}
4767 * reference to an empty one.
4768 * <p>
4769 * This method returns an empty array for a {@code null} input array.
4770 * </p>
4771 * <p>
4772 * As a memory optimizing technique an empty array passed in will be overridden with
4773 * the empty {@code public static} references in this class.
4774 * </p>
4775 *
4776 * @param array the array to check for {@code null} or empty.
4777 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4778 * @since 2.5
4779 */
4780 public static float[] nullToEmpty(final float[] array) {
4781 return isEmpty(array) ? EMPTY_FLOAT_ARRAY : array;
4782 }
4783
4784 /**
4785 * Defensive programming technique to change a {@code null}
4786 * reference to an empty one.
4787 * <p>
4788 * This method returns an empty array for a {@code null} input array.
4789 * </p>
4790 * <p>
4791 * As a memory optimizing technique an empty array passed in will be overridden with
4792 * the empty {@code public static} references in this class.
4793 * </p>
4794 *
4795 * @param array the array to check for {@code null} or empty.
4796 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4797 * @since 2.5
4798 */
4799 public static Float[] nullToEmpty(final Float[] array) {
4800 return nullTo(array, EMPTY_FLOAT_OBJECT_ARRAY);
4801 }
4802
4803 /**
4804 * Defensive programming technique to change a {@code null}
4805 * reference to an empty one.
4806 * <p>
4807 * This method returns an empty array for a {@code null} input array.
4808 * </p>
4809 * <p>
4810 * As a memory optimizing technique an empty array passed in will be overridden with
4811 * the empty {@code public static} references in this class.
4812 * </p>
4813 *
4814 * @param array the array to check for {@code null} or empty.
4815 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4816 * @since 2.5
4817 */
4818 public static int[] nullToEmpty(final int[] array) {
4819 return isEmpty(array) ? EMPTY_INT_ARRAY : array;
4820 }
4821
4822 /**
4823 * Defensive programming technique to change a {@code null}
4824 * reference to an empty one.
4825 * <p>
4826 * This method returns an empty array for a {@code null} input array.
4827 * </p>
4828 * <p>
4829 * As a memory optimizing technique an empty array passed in will be overridden with
4830 * the empty {@code public static} references in this class.
4831 * </p>
4832 *
4833 * @param array the array to check for {@code null} or empty.
4834 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4835 * @since 2.5
4836 */
4837 public static Integer[] nullToEmpty(final Integer[] array) {
4838 return nullTo(array, EMPTY_INTEGER_OBJECT_ARRAY);
4839 }
4840
4841 /**
4842 * Defensive programming technique to change a {@code null}
4843 * reference to an empty one.
4844 * <p>
4845 * This method returns an empty array for a {@code null} input array.
4846 * </p>
4847 * <p>
4848 * As a memory optimizing technique an empty array passed in will be overridden with
4849 * the empty {@code public static} references in this class.
4850 * </p>
4851 *
4852 * @param array the array to check for {@code null} or empty.
4853 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4854 * @since 2.5
4855 */
4856 public static long[] nullToEmpty(final long[] array) {
4857 return isEmpty(array) ? EMPTY_LONG_ARRAY : array;
4858 }
4859
4860 /**
4861 * Defensive programming technique to change a {@code null}
4862 * reference to an empty one.
4863 * <p>
4864 * This method returns an empty array for a {@code null} input array.
4865 * </p>
4866 * <p>
4867 * As a memory optimizing technique an empty array passed in will be overridden with
4868 * the empty {@code public static} references in this class.
4869 * </p>
4870 *
4871 * @param array the array to check for {@code null} or empty.
4872 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4873 * @since 2.5
4874 */
4875 public static Long[] nullToEmpty(final Long[] array) {
4876 return nullTo(array, EMPTY_LONG_OBJECT_ARRAY);
4877 }
4878
4879 /**
4880 * Defensive programming technique to change a {@code null}
4881 * reference to an empty one.
4882 * <p>
4883 * This method returns an empty array for a {@code null} input array.
4884 * </p>
4885 * <p>
4886 * As a memory optimizing technique an empty array passed in will be overridden with
4887 * the empty {@code public static} references in this class.
4888 * </p>
4889 *
4890 * @param array the array to check for {@code null} or empty.
4891 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4892 * @since 2.5
4893 */
4894 public static Object[] nullToEmpty(final Object[] array) {
4895 return nullTo(array, EMPTY_OBJECT_ARRAY);
4896 }
4897
4898 /**
4899 * Defensive programming technique to change a {@code null}
4900 * reference to an empty one.
4901 * <p>
4902 * This method returns an empty array for a {@code null} input array.
4903 * </p>
4904 * <p>
4905 * As a memory optimizing technique an empty array passed in will be overridden with
4906 * the empty {@code public static} references in this class.
4907 * </p>
4908 *
4909 * @param array the array to check for {@code null} or empty.
4910 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4911 * @since 2.5
4912 */
4913 public static short[] nullToEmpty(final short[] array) {
4914 return isEmpty(array) ? EMPTY_SHORT_ARRAY : array;
4915 }
4916
4917 /**
4918 * Defensive programming technique to change a {@code null}
4919 * reference to an empty one.
4920 * <p>
4921 * This method returns an empty array for a {@code null} input array.
4922 * </p>
4923 * <p>
4924 * As a memory optimizing technique an empty array passed in will be overridden with
4925 * the empty {@code public static} references in this class.
4926 * </p>
4927 *
4928 * @param array the array to check for {@code null} or empty.
4929 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4930 * @since 2.5
4931 */
4932 public static Short[] nullToEmpty(final Short[] array) {
4933 return nullTo(array, EMPTY_SHORT_OBJECT_ARRAY);
4934 }
4935
4936 /**
4937 * Defensive programming technique to change a {@code null}
4938 * reference to an empty one.
4939 * <p>
4940 * This method returns an empty array for a {@code null} input array.
4941 * </p>
4942 * <p>
4943 * As a memory optimizing technique an empty array passed in will be overridden with
4944 * the empty {@code public static} references in this class.
4945 * </p>
4946 *
4947 * @param array the array to check for {@code null} or empty.
4948 * @return the same array, {@code public static} empty array if {@code null} or empty input.
4949 * @since 2.5
4950 */
4951 public static String[] nullToEmpty(final String[] array) {
4952 return nullTo(array, EMPTY_STRING_ARRAY);
4953 }
4954
4955 /**
4956 * Defensive programming technique to change a {@code null}
4957 * reference to an empty one.
4958 * <p>
4959 * This method returns an empty array for a {@code null} input array.
4960 * </p>
4961 *
4962 * @param array the array to check for {@code null} or empty.
4963 * @param type the class representation of the desired array.
4964 * @param <T> the class type.
4965 * @return the same array, {@code public static} empty array if {@code null}.
4966 * @throws IllegalArgumentException if the type argument is null.
4967 * @since 3.5
4968 */
4969 public static <T> T[] nullToEmpty(final T[] array, final Class<T[]> type) {
4970 if (type == null) {
4971 throw new IllegalArgumentException("The type must not be null");
4972 }
4973 if (array == null) {
4974 return type.cast(Array.newInstance(type.getComponentType(), 0));
4975 }
4976 return array;
4977 }
4978
4979 /**
4980 * Gets the {@link ThreadLocalRandom} for {@code shuffle} methods that don't take a {@link Random} argument.
4981 *
4982 * @return the current ThreadLocalRandom.
4983 */
4984 private static ThreadLocalRandom random() {
4985 return ThreadLocalRandom.current();
4986 }
4987
4988 /**
4989 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
4990 * indices).
4991 * <p>
4992 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
4993 * returned array is always the same as that of the input array.
4994 * </p>
4995 * <p>
4996 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
4997 * </p>
4998 *
4999 * <pre>
5000 * ArrayUtils.remove([true], 0) = []
5001 * ArrayUtils.remove([true, false], 0) = [false]
5002 * ArrayUtils.remove([true, false], 1) = [true]
5003 * ArrayUtils.remove([true, true, false], 1) = [true, false]
5004 * </pre>
5005 *
5006 * @param array the array to remove the element from, may not be {@code null}.
5007 * @param index the position of the element to be removed.
5008 * @return A new array containing the existing elements except the element at the specified position.
5009 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5010 * @since 2.1
5011 */
5012 public static boolean[] remove(final boolean[] array, final int index) {
5013 return (boolean[]) remove((Object) array, index);
5014 }
5015
5016 /**
5017 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5018 * indices).
5019 * <p>
5020 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5021 * returned array is always the same as that of the input array.
5022 * </p>
5023 * <p>
5024 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5025 * </p>
5026 *
5027 * <pre>
5028 * ArrayUtils.remove([1], 0) = []
5029 * ArrayUtils.remove([1, 0], 0) = [0]
5030 * ArrayUtils.remove([1, 0], 1) = [1]
5031 * ArrayUtils.remove([1, 0, 1], 1) = [1, 1]
5032 * </pre>
5033 *
5034 * @param array the array to remove the element from, may not be {@code null}.
5035 * @param index the position of the element to be removed.
5036 * @return A new array containing the existing elements except the element at the specified position.
5037 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5038 * @since 2.1
5039 */
5040 public static byte[] remove(final byte[] array, final int index) {
5041 return (byte[]) remove((Object) array, index);
5042 }
5043
5044 /**
5045 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5046 * indices).
5047 * <p>
5048 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5049 * returned array is always the same as that of the input array.
5050 * </p>
5051 * <p>
5052 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5053 * </p>
5054 *
5055 * <pre>
5056 * ArrayUtils.remove(['a'], 0) = []
5057 * ArrayUtils.remove(['a', 'b'], 0) = ['b']
5058 * ArrayUtils.remove(['a', 'b'], 1) = ['a']
5059 * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
5060 * </pre>
5061 *
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 at the specified position.
5065 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5066 * @since 2.1
5067 */
5068 public static char[] remove(final char[] array, final int index) {
5069 return (char[]) remove((Object) array, index);
5070 }
5071
5072 /**
5073 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5074 * indices).
5075 * <p>
5076 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5077 * returned array is always the same as that of the input array.
5078 * </p>
5079 * <p>
5080 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5081 * </p>
5082 *
5083 * <pre>
5084 * ArrayUtils.remove([1.1], 0) = []
5085 * ArrayUtils.remove([2.5, 6.0], 0) = [6.0]
5086 * ArrayUtils.remove([2.5, 6.0], 1) = [2.5]
5087 * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
5088 * </pre>
5089 *
5090 * @param array the array to remove the element from, may not be {@code null}.
5091 * @param index the position of the element to be removed.
5092 * @return A new array containing the existing elements except the element at the specified position.
5093 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5094 * @since 2.1
5095 */
5096 public static double[] remove(final double[] array, final int index) {
5097 return (double[]) remove((Object) array, index);
5098 }
5099
5100 /**
5101 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5102 * indices).
5103 * <p>
5104 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5105 * returned array is always the same as that of the input array.
5106 * </p>
5107 * <p>
5108 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5109 * </p>
5110 *
5111 * <pre>
5112 * ArrayUtils.remove([1.1], 0) = []
5113 * ArrayUtils.remove([2.5, 6.0], 0) = [6.0]
5114 * ArrayUtils.remove([2.5, 6.0], 1) = [2.5]
5115 * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
5116 * </pre>
5117 *
5118 * @param array the array to remove the element from, may not be {@code null}.
5119 * @param index the position of the element to be removed.
5120 * @return A new array containing the existing elements except the element at the specified position.
5121 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5122 * @since 2.1
5123 */
5124 public static float[] remove(final float[] array, final int index) {
5125 return (float[]) remove((Object) array, index);
5126 }
5127
5128 /**
5129 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5130 * indices).
5131 * <p>
5132 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5133 * returned array is always the same as that of the input array.
5134 * </p>
5135 * <p>
5136 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5137 * </p>
5138 *
5139 * <pre>
5140 * ArrayUtils.remove([1], 0) = []
5141 * ArrayUtils.remove([2, 6], 0) = [6]
5142 * ArrayUtils.remove([2, 6], 1) = [2]
5143 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
5144 * </pre>
5145 *
5146 * @param array the array to remove the element from, may not be {@code null}.
5147 * @param index the position of the element to be removed.
5148 * @return A new array containing the existing elements except the element at the specified position.
5149 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5150 * @since 2.1
5151 */
5152 public static int[] remove(final int[] array, final int index) {
5153 return (int[]) remove((Object) array, index);
5154 }
5155
5156 /**
5157 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5158 * indices).
5159 * <p>
5160 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5161 * returned array is always the same as that of the input array.
5162 * </p>
5163 * <p>
5164 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5165 * </p>
5166 *
5167 * <pre>
5168 * ArrayUtils.remove([1], 0) = []
5169 * ArrayUtils.remove([2, 6], 0) = [6]
5170 * ArrayUtils.remove([2, 6], 1) = [2]
5171 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
5172 * </pre>
5173 *
5174 * @param array the array to remove the element from, may not be {@code null}.
5175 * @param index the position of the element to be removed.
5176 * @return A new array containing the existing elements except the element at the specified position.
5177 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5178 * @since 2.1
5179 */
5180 public static long[] remove(final long[] array, final int index) {
5181 return (long[]) remove((Object) array, index);
5182 }
5183
5184 /**
5185 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5186 * indices).
5187 * <p>
5188 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5189 * returned array is always the same as that of the input array.
5190 * </p>
5191 * <p>
5192 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5193 * </p>
5194 *
5195 * @param array the array to remove the element from, may not be {@code null}.
5196 * @param index the position of the element to be removed.
5197 * @return A new array containing the existing elements except the element at the specified position.
5198 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5199 * @since 2.1
5200 */
5201 private static Object remove(final Object array, final int index) {
5202 final int length = getLength(array);
5203 if (index < 0 || index >= length) {
5204 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
5205 }
5206 final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
5207 System.arraycopy(array, 0, result, 0, index);
5208 if (index < length - 1) {
5209 System.arraycopy(array, index + 1, result, index, length - index - 1);
5210 }
5211 return result;
5212 }
5213
5214 /**
5215 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5216 * indices).
5217 * <p>
5218 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5219 * returned array is always the same as that of the input array.
5220 * </p>
5221 * <p>
5222 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5223 * </p>
5224 *
5225 * <pre>
5226 * ArrayUtils.remove([1], 0) = []
5227 * ArrayUtils.remove([2, 6], 0) = [6]
5228 * ArrayUtils.remove([2, 6], 1) = [2]
5229 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
5230 * </pre>
5231 *
5232 * @param array the array to remove the element from, may not be {@code null}.
5233 * @param index the position of the element to be removed.
5234 * @return A new array containing the existing elements except the element at the specified position.
5235 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5236 * @since 2.1
5237 */
5238 public static short[] remove(final short[] array, final int index) {
5239 return (short[]) remove((Object) array, index);
5240 }
5241
5242 /**
5243 * Removes the element at the specified position from the specified array. All subsequent elements are shifted to the left (subtracts one from their
5244 * indices).
5245 * <p>
5246 * This method returns a new array with the same elements of the input array except the element on the specified position. The component type of the
5247 * returned array is always the same as that of the input array.
5248 * </p>
5249 * <p>
5250 * If the input array is {@code null}, an IndexOutOfBoundsException will be thrown, because in that case no valid index can be specified.
5251 * </p>
5252 *
5253 * <pre>
5254 * ArrayUtils.remove(["a"], 0) = []
5255 * ArrayUtils.remove(["a", "b"], 0) = ["b"]
5256 * ArrayUtils.remove(["a", "b"], 1) = ["a"]
5257 * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
5258 * </pre>
5259 *
5260 * @param <T> the component type of the array.
5261 * @param array the array to remove the element from, may not be {@code null}.
5262 * @param index the position of the element to be removed.
5263 * @return A new array containing the existing elements except the element at the specified position.
5264 * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= array.length), or if the array is {@code null}.
5265 * @since 2.1
5266 */
5267 @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
5268 public static <T> T[] remove(final T[] array, final int index) {
5269 return (T[]) remove((Object) array, index);
5270 }
5271
5272 /**
5273 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5274 * <p>
5275 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5276 * array is always the same as that of the input array.
5277 * </p>
5278 * <p>
5279 * If the input array is {@code null}, then return {@code null}.
5280 * </p>
5281 *
5282 * <pre>
5283 * ArrayUtils.removeAll([true, false, true], 0, 2) = [false]
5284 * ArrayUtils.removeAll([true, false, true], 1, 2) = [true]
5285 * </pre>
5286 *
5287 * @param array the array to remove the element from, may not be {@code null}.
5288 * @param indices the positions of the elements to be removed.
5289 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5290 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5291 * @since 3.0.1
5292 */
5293 public static boolean[] removeAll(final boolean[] array, final int... indices) {
5294 return (boolean[]) removeAll((Object) array, indices);
5295 }
5296
5297 /**
5298 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5299 * <p>
5300 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5301 * array is always the same as that of the input array.
5302 * </p>
5303 * <p>
5304 * If the input array is {@code null}, then return {@code null}.
5305 * </p>
5306 *
5307 * <pre>
5308 * ArrayUtils.removeAll([1], 0) = []
5309 * ArrayUtils.removeAll([2, 6], 0) = [6]
5310 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5311 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5312 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5313 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5314 * </pre>
5315 *
5316 * @param array the array to remove the element from, may not be {@code null}.
5317 * @param indices the positions of the elements to be removed.
5318 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5319 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5320 * @since 3.0.1
5321 */
5322 public static byte[] removeAll(final byte[] array, final int... indices) {
5323 return (byte[]) removeAll((Object) array, indices);
5324 }
5325
5326 /**
5327 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5328 * <p>
5329 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5330 * array is always the same as that of the input array.
5331 * </p>
5332 * <p>
5333 * If the input array is {@code null}, then return {@code null}.
5334 * </p>
5335 *
5336 * <pre>
5337 * ArrayUtils.removeAll([1], 0) = []
5338 * ArrayUtils.removeAll([2, 6], 0) = [6]
5339 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5340 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5341 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5342 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5343 * </pre>
5344 *
5345 * @param array the array to remove the element from, may not be {@code null}.
5346 * @param indices the positions of the elements to be removed.
5347 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5348 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5349 * @since 3.0.1
5350 */
5351 public static char[] removeAll(final char[] array, final int... indices) {
5352 return (char[]) removeAll((Object) array, indices);
5353 }
5354
5355 /**
5356 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5357 * <p>
5358 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5359 * array is always the same as that of the input array.
5360 * </p>
5361 * <p>
5362 * If the input array is {@code null}, then return {@code null}.
5363 * </p>
5364 *
5365 * <pre>
5366 * ArrayUtils.removeAll([1], 0) = []
5367 * ArrayUtils.removeAll([2, 6], 0) = [6]
5368 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5369 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5370 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5371 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5372 * </pre>
5373 *
5374 * @param array the array to remove the element from, may not be {@code null}.
5375 * @param indices the positions of the elements to be removed.
5376 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5377 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5378 * @since 3.0.1
5379 */
5380 public static double[] removeAll(final double[] array, final int... indices) {
5381 return (double[]) removeAll((Object) array, indices);
5382 }
5383
5384 /**
5385 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5386 * <p>
5387 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5388 * array is always the same as that of the input array.
5389 * </p>
5390 * <p>
5391 * If the input array is {@code null}, then return {@code null}.
5392 * </p>
5393 *
5394 * <pre>
5395 * ArrayUtils.removeAll([1], 0) = []
5396 * ArrayUtils.removeAll([2, 6], 0) = [6]
5397 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5398 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5399 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5400 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5401 * </pre>
5402 *
5403 * @param array the array to remove the element from, may not be {@code null}.
5404 * @param indices the positions of the elements to be removed.
5405 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5406 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5407 * @since 3.0.1
5408 */
5409 public static float[] removeAll(final float[] array, final int... indices) {
5410 return (float[]) removeAll((Object) array, indices);
5411 }
5412
5413 /**
5414 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5415 * <p>
5416 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5417 * array is always the same as that of the input array.
5418 * </p>
5419 * <p>
5420 * If the input array is {@code null}, then return {@code null}.
5421 * </p>
5422 *
5423 * <pre>
5424 * ArrayUtils.removeAll([1], 0) = []
5425 * ArrayUtils.removeAll([2, 6], 0) = [6]
5426 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5427 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5428 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5429 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5430 * </pre>
5431 *
5432 * @param array the array to remove the element from, may not be {@code null}.
5433 * @param indices the positions of the elements to be removed.
5434 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5435 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5436 * @since 3.0.1
5437 */
5438 public static int[] removeAll(final int[] array, final int... indices) {
5439 return (int[]) removeAll((Object) array, indices);
5440 }
5441
5442 /**
5443 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5444 * <p>
5445 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5446 * array is always the same as that of the input array.
5447 * </p>
5448 * <p>
5449 * If the input array is {@code null}, then return {@code null}.
5450 * </p>
5451 *
5452 * <pre>
5453 * ArrayUtils.removeAll([1], 0) = []
5454 * ArrayUtils.removeAll([2, 6], 0) = [6]
5455 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5456 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5457 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5458 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5459 * </pre>
5460 *
5461 * @param array the array to remove the element from, may not be {@code null}.
5462 * @param indices the positions of the elements to be removed.
5463 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5464 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5465 * @since 3.0.1
5466 */
5467 public static long[] removeAll(final long[] array, final int... indices) {
5468 return (long[]) removeAll((Object) array, indices);
5469 }
5470
5471 /**
5472 * Removes multiple array elements specified by index.
5473 *
5474 * @param array source
5475 * @param indices to remove
5476 * @return new array of same type minus elements specified by unique values of {@code indices}
5477 */
5478 // package protected for access by unit tests
5479 static Object removeAll(final Object array, final int... indices) {
5480 if (array == null) {
5481 return null;
5482 }
5483 final int length = getLength(array);
5484 int diff = 0; // number of distinct indexes, i.e. number of entries that will be removed
5485 final int[] clonedIndices = ArraySorter.sort(clone(indices));
5486 // identify length of result array
5487 if (isNotEmpty(clonedIndices)) {
5488 int i = clonedIndices.length;
5489 int prevIndex = length;
5490 while (--i >= 0) {
5491 final int index = clonedIndices[i];
5492 if (index < 0 || index >= length) {
5493 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
5494 }
5495 if (index >= prevIndex) {
5496 continue;
5497 }
5498 diff++;
5499 prevIndex = index;
5500 }
5501 }
5502 // create result array
5503 final Object result = Array.newInstance(array.getClass().getComponentType(), length - diff);
5504 if (diff < length && clonedIndices != null) {
5505 int end = length; // index just after last copy
5506 int dest = length - diff; // number of entries so far not copied
5507 for (int i = clonedIndices.length - 1; i >= 0; i--) {
5508 final int index = clonedIndices[i];
5509 if (end - index > 1) { // same as (cp > 0)
5510 final int cp = end - index - 1;
5511 dest -= cp;
5512 System.arraycopy(array, index + 1, result, dest, cp);
5513 // After this copy, we still have room for dest items.
5514 }
5515 end = index;
5516 }
5517 if (end > 0) {
5518 System.arraycopy(array, 0, result, 0, end);
5519 }
5520 }
5521 return result;
5522 }
5523
5524 /**
5525 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5526 * <p>
5527 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5528 * array is always the same as that of the input array.
5529 * </p>
5530 * <p>
5531 * If the input array is {@code null}, then return {@code null}.
5532 * </p>
5533 *
5534 * <pre>
5535 * ArrayUtils.removeAll([1], 0) = []
5536 * ArrayUtils.removeAll([2, 6], 0) = [6]
5537 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5538 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5539 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5540 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5541 * </pre>
5542 *
5543 * @param array the array to remove the element from, may not be {@code null}.
5544 * @param indices the positions of the elements to be removed.
5545 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5546 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5547 * @since 3.0.1
5548 */
5549 public static short[] removeAll(final short[] array, final int... indices) {
5550 return (short[]) removeAll((Object) array, indices);
5551 }
5552
5553 /**
5554 * Removes the elements at the specified positions from the specified array. All remaining elements are shifted to the left.
5555 * <p>
5556 * This method returns a new array with the same elements of the input array except those at the specified positions. The component type of the returned
5557 * array is always the same as that of the input array.
5558 * </p>
5559 * <p>
5560 * If the input array is {@code null}, then return {@code null}.
5561 * </p>
5562 *
5563 * <pre>
5564 * ArrayUtils.removeAll(["a", "b", "c"], 0, 2) = ["b"]
5565 * ArrayUtils.removeAll(["a", "b", "c"], 1, 2) = ["a"]
5566 * </pre>
5567 *
5568 * @param <T> the component type of the array.
5569 * @param array the array to remove the element from, may not be {@code null}.
5570 * @param indices the positions of the elements to be removed.
5571 * @return A new array containing the existing elements except those at the specified positions or {@code null} if the input array is {@code null}.
5572 * @throws IndexOutOfBoundsException if any index is out of range (index < 0 || index >= array.length).
5573 * @since 3.0.1
5574 */
5575 @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
5576 public static <T> T[] removeAll(final T[] array, final int... indices) {
5577 return (T[]) removeAll((Object) array, indices);
5578 }
5579
5580 /**
5581 * Removes the occurrences of the specified element from the specified boolean 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 array the input array, will not be modified, and may be {@code null}.
5589 * @param element the element to remove.
5590 * @return A new array containing the existing elements except the occurrences of the specified element.
5591 * @since 3.5
5592 * @deprecated Use {@link #removeAllOccurrences(boolean[], boolean)}.
5593 */
5594 @Deprecated
5595 public static boolean[] removeAllOccurences(final boolean[] array, final boolean element) {
5596 return (boolean[]) removeAt(array, indexesOf(array, element));
5597 }
5598
5599 /**
5600 * Removes the occurrences of the specified element from the specified byte array.
5601 * <p>
5602 * All subsequent elements are shifted to the left (subtracts one from their indices).
5603 * If the array doesn't contain such an element, no elements are removed from the array.
5604 * {@code null} will be returned if the input array is {@code null}.
5605 * </p>
5606 *
5607 * @param array the input array, will not be modified, and may be {@code null}.
5608 * @param element the element to remove.
5609 * @return A new array containing the existing elements except the occurrences of the specified element.
5610 * @since 3.5
5611 * @deprecated Use {@link #removeAllOccurrences(byte[], byte)}.
5612 */
5613 @Deprecated
5614 public static byte[] removeAllOccurences(final byte[] array, final byte element) {
5615 return (byte[]) removeAt(array, indexesOf(array, element));
5616 }
5617
5618 /**
5619 * Removes the occurrences of the specified element from the specified char array.
5620 * <p>
5621 * All subsequent elements are shifted to the left (subtracts one from their indices).
5622 * If the array doesn't contain such an element, no elements are removed from the array.
5623 * {@code null} will be returned if the input array is {@code null}.
5624 * </p>
5625 *
5626 * @param array the input array, will not be modified, and may be {@code null}.
5627 * @param element the element to remove.
5628 * @return A new array containing the existing elements except the occurrences of the specified element.
5629 * @since 3.5
5630 * @deprecated Use {@link #removeAllOccurrences(char[], char)}.
5631 */
5632 @Deprecated
5633 public static char[] removeAllOccurences(final char[] array, final char element) {
5634 return (char[]) removeAt(array, indexesOf(array, element));
5635 }
5636
5637 /**
5638 * Removes the occurrences of the specified element from the specified double array.
5639 * <p>
5640 * All subsequent elements are shifted to the left (subtracts one from their indices).
5641 * If the array doesn't contain such an element, no elements are removed from the array.
5642 * {@code null} will be returned if the input array is {@code null}.
5643 * </p>
5644 *
5645 * @param array the input array, will not be modified, and may be {@code null}.
5646 * @param element the element to remove.
5647 * @return A new array containing the existing elements except the occurrences of the specified element.
5648 * @since 3.5
5649 * @deprecated Use {@link #removeAllOccurrences(double[], double)}.
5650 */
5651 @Deprecated
5652 public static double[] removeAllOccurences(final double[] array, final double element) {
5653 return (double[]) removeAt(array, indexesOf(array, element));
5654 }
5655
5656 /**
5657 * Removes the occurrences of the specified element from the specified float array.
5658 * <p>
5659 * All subsequent elements are shifted to the left (subtracts one from their indices).
5660 * If the array doesn't contain such an element, no elements are removed from the array.
5661 * {@code null} will be returned if the input array is {@code null}.
5662 * </p>
5663 *
5664 * @param array the input array, will not be modified, and may be {@code null}.
5665 * @param element the element to remove.
5666 * @return A new array containing the existing elements except the occurrences of the specified element.
5667 * @since 3.5
5668 * @deprecated Use {@link #removeAllOccurrences(float[], float)}.
5669 */
5670 @Deprecated
5671 public static float[] removeAllOccurences(final float[] array, final float element) {
5672 return (float[]) removeAt(array, indexesOf(array, element));
5673 }
5674
5675 /**
5676 * Removes the occurrences of the specified element from the specified int array.
5677 * <p>
5678 * All subsequent elements are shifted to the left (subtracts one from their indices).
5679 * If the array doesn't contain such an element, no elements are removed from the array.
5680 * {@code null} will be returned if the input array is {@code null}.
5681 * </p>
5682 *
5683 * @param array the input array, will not be modified, and may be {@code null}.
5684 * @param element the element to remove.
5685 * @return A new array containing the existing elements except the occurrences of the specified element.
5686 * @since 3.5
5687 * @deprecated Use {@link #removeAllOccurrences(int[], int)}.
5688 */
5689 @Deprecated
5690 public static int[] removeAllOccurences(final int[] array, final int element) {
5691 return (int[]) removeAt(array, indexesOf(array, element));
5692 }
5693
5694 /**
5695 * Removes the occurrences of the specified element from the specified long array.
5696 * <p>
5697 * All subsequent elements are shifted to the left (subtracts one from their indices).
5698 * If the array doesn't contain such an element, no elements are removed from the array.
5699 * {@code null} will be returned if the input array is {@code null}.
5700 * </p>
5701 *
5702 * @param array the input array, will not be modified, and may be {@code null}.
5703 * @param element the element to remove.
5704 * @return A new array containing the existing elements except the occurrences of the specified element.
5705 * @since 3.5
5706 * @deprecated Use {@link #removeAllOccurrences(long[], long)}.
5707 */
5708 @Deprecated
5709 public static long[] removeAllOccurences(final long[] array, final long element) {
5710 return (long[]) removeAt(array, indexesOf(array, element));
5711 }
5712
5713 /**
5714 * Removes the occurrences of the specified element from the specified short array.
5715 * <p>
5716 * All subsequent elements are shifted to the left (subtracts one from their indices).
5717 * If the array doesn't contain such an element, no elements are removed from the array.
5718 * {@code null} will be returned if the input array is {@code null}.
5719 * </p>
5720 *
5721 * @param array the input array, will not be modified, and may be {@code null}.
5722 * @param element the element to remove.
5723 * @return A new array containing the existing elements except the occurrences of the specified element.
5724 * @since 3.5
5725 * @deprecated Use {@link #removeAllOccurrences(short[], short)}.
5726 */
5727 @Deprecated
5728 public static short[] removeAllOccurences(final short[] array, final short element) {
5729 return (short[]) removeAt(array, indexesOf(array, element));
5730 }
5731
5732 /**
5733 * Removes the occurrences of the specified element from the specified array.
5734 * <p>
5735 * All subsequent elements are shifted to the left (subtracts one from their indices).
5736 * If the array doesn't contain such an element, no elements are removed from the array.
5737 * {@code null} will be returned if the input array is {@code null}.
5738 * </p>
5739 *
5740 * @param <T> the type of object in the array, may be {@code null}.
5741 * @param array the input array, will not be modified, and may be {@code null}.
5742 * @param element the element to remove, may be {@code null}.
5743 * @return A new array containing the existing elements except the occurrences of the specified element.
5744 * @since 3.5
5745 * @deprecated Use {@link #removeAllOccurrences(Object[], Object)}.
5746 */
5747 @Deprecated
5748 public static <T> T[] removeAllOccurences(final T[] array, final T element) {
5749 return (T[]) removeAt(array, indexesOf(array, element));
5750 }
5751
5752 /**
5753 * Removes the occurrences of the specified element from the specified boolean array.
5754 * <p>
5755 * All subsequent elements are shifted to the left (subtracts one from their indices).
5756 * If the array doesn't contain such an element, no elements are removed from the array.
5757 * {@code null} will be returned if the input array is {@code null}.
5758 * </p>
5759 *
5760 * @param array the input array, will not be modified, and may be {@code null}.
5761 * @param element the element to remove.
5762 * @return A new array containing the existing elements except the occurrences of the specified element.
5763 * @since 3.10
5764 */
5765 public static boolean[] removeAllOccurrences(final boolean[] array, final boolean element) {
5766 return (boolean[]) removeAt(array, indexesOf(array, element));
5767 }
5768
5769 /**
5770 * Removes the occurrences of the specified element from the specified byte array.
5771 * <p>
5772 * All subsequent elements are shifted to the left (subtracts one from their indices).
5773 * If the array doesn't contain such an element, no elements are removed from the array.
5774 * {@code null} will be returned if the input array is {@code null}.
5775 * </p>
5776 *
5777 * @param array the input array, will not be modified, and may be {@code null}.
5778 * @param element the element to remove.
5779 * @return A new array containing the existing elements except the occurrences of the specified element.
5780 * @since 3.10
5781 */
5782 public static byte[] removeAllOccurrences(final byte[] array, final byte element) {
5783 return (byte[]) removeAt(array, indexesOf(array, element));
5784 }
5785
5786 /**
5787 * Removes the occurrences of the specified element from the specified char array.
5788 * <p>
5789 * All subsequent elements are shifted to the left (subtracts one from their indices).
5790 * If the array doesn't contain such an element, no elements are removed from the array.
5791 * {@code null} will be returned if the input array is {@code null}.
5792 * </p>
5793 *
5794 * @param array the input array, will not be modified, and may be {@code null}.
5795 * @param element the element to remove.
5796 * @return A new array containing the existing elements except the occurrences of the specified element.
5797 * @since 3.10
5798 */
5799 public static char[] removeAllOccurrences(final char[] array, final char element) {
5800 return (char[]) removeAt(array, indexesOf(array, element));
5801 }
5802
5803 /**
5804 * Removes the occurrences of the specified element from the specified double array.
5805 * <p>
5806 * All subsequent elements are shifted to the left (subtracts one from their indices).
5807 * If the array doesn't contain such an element, no elements are removed from the array.
5808 * {@code null} will be returned if the input array is {@code null}.
5809 * </p>
5810 *
5811 * @param array the input array, will not be modified, and may be {@code null}.
5812 * @param element the element to remove.
5813 * @return A new array containing the existing elements except the occurrences of the specified element.
5814 * @since 3.10
5815 */
5816 public static double[] removeAllOccurrences(final double[] array, final double element) {
5817 return (double[]) removeAt(array, indexesOf(array, element));
5818 }
5819
5820 /**
5821 * Removes the occurrences of the specified element from the specified float array.
5822 * <p>
5823 * All subsequent elements are shifted to the left (subtracts one from their indices).
5824 * If the array doesn't contain such an element, no elements are removed from the array.
5825 * {@code null} will be returned if the input array is {@code null}.
5826 * </p>
5827 *
5828 * @param array the input array, will not be modified, and may be {@code null}.
5829 * @param element the element to remove.
5830 * @return A new array containing the existing elements except the occurrences of the specified element.
5831 * @since 3.10
5832 */
5833 public static float[] removeAllOccurrences(final float[] array, final float element) {
5834 return (float[]) removeAt(array, indexesOf(array, element));
5835 }
5836
5837 /**
5838 * Removes the occurrences of the specified element from the specified int array.
5839 * <p>
5840 * All subsequent elements are shifted to the left (subtracts one from their indices).
5841 * If the array doesn't contain such an element, no elements are removed from the array.
5842 * {@code null} will be returned if the input array is {@code null}.
5843 * </p>
5844 *
5845 * @param array the input array, will not be modified, and may be {@code null}.
5846 * @param element the element to remove.
5847 * @return A new array containing the existing elements except the occurrences of the specified element.
5848 * @since 3.10
5849 */
5850 public static int[] removeAllOccurrences(final int[] array, final int element) {
5851 return (int[]) removeAt(array, indexesOf(array, element));
5852 }
5853
5854 /**
5855 * Removes the occurrences of the specified element from the specified long array.
5856 * <p>
5857 * All subsequent elements are shifted to the left (subtracts one from their indices).
5858 * If the array doesn't contain such an element, no elements are removed from the array.
5859 * {@code null} will be returned if the input array is {@code null}.
5860 * </p>
5861 *
5862 * @param array the input array, will not be modified, and may be {@code null}.
5863 * @param element the element to remove.
5864 * @return A new array containing the existing elements except the occurrences of the specified element.
5865 * @since 3.10
5866 */
5867 public static long[] removeAllOccurrences(final long[] array, final long element) {
5868 return (long[]) removeAt(array, indexesOf(array, element));
5869 }
5870
5871 /**
5872 * Removes the occurrences of the specified element from the specified short array.
5873 * <p>
5874 * All subsequent elements are shifted to the left (subtracts one from their indices).
5875 * If the array doesn't contain such an element, no elements are removed from the array.
5876 * {@code null} will be returned if the input array is {@code null}.
5877 * </p>
5878 *
5879 * @param array the input array, will not be modified, and may be {@code null}.
5880 * @param element the element to remove.
5881 * @return A new array containing the existing elements except the occurrences of the specified element.
5882 * @since 3.10
5883 */
5884 public static short[] removeAllOccurrences(final short[] array, final short element) {
5885 return (short[]) removeAt(array, indexesOf(array, element));
5886 }
5887
5888 /**
5889 * Removes the occurrences of the specified element from the specified array.
5890 * <p>
5891 * All subsequent elements are shifted to the left (subtracts one from their indices).
5892 * If the array doesn't contain such an element, no elements are removed from the array.
5893 * {@code null} will be returned if the input array is {@code null}.
5894 * </p>
5895 *
5896 * @param <T> the type of object in the array, may be {@code null}.
5897 * @param array the input array, will not be modified, and may be {@code null}.
5898 * @param element the element to remove, may be {@code null}.
5899 * @return A new array containing the existing elements except the occurrences of the specified element.
5900 * @since 3.10
5901 */
5902 public static <T> T[] removeAllOccurrences(final T[] array, final T element) {
5903 return (T[]) removeAt(array, indexesOf(array, element));
5904 }
5905
5906 /**
5907 * Removes multiple array elements specified by indices.
5908 *
5909 * @param array the input array, will not be modified, and may be {@code null}.
5910 * @param indices to remove.
5911 * @return new array of same type minus elements specified by the set bits in {@code indices}.
5912 */
5913 // package protected for access by unit tests
5914 static Object removeAt(final Object array, final BitSet indices) {
5915 if (array == null) {
5916 return null;
5917 }
5918 final int srcLength = getLength(array);
5919 // No need to check maxIndex here, because method only currently called from removeElements()
5920 // which guarantee to generate only valid bit entries.
5921 // final int maxIndex = indices.length();
5922 // if (maxIndex > srcLength) {
5923 // throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength);
5924 // }
5925 final int removals = indices.cardinality(); // true bits are items to remove
5926 final Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals);
5927 int srcIndex = 0;
5928 int destIndex = 0;
5929 int count;
5930 int set;
5931 while ((set = indices.nextSetBit(srcIndex)) != -1) {
5932 count = set - srcIndex;
5933 if (count > 0) {
5934 System.arraycopy(array, srcIndex, result, destIndex, count);
5935 destIndex += count;
5936 }
5937 srcIndex = indices.nextClearBit(set);
5938 }
5939 count = srcLength - srcIndex;
5940 if (count > 0) {
5941 System.arraycopy(array, srcIndex, result, destIndex, count);
5942 }
5943 return result;
5944 }
5945
5946 /**
5947 * Removes the first occurrence of the specified element from the
5948 * specified array. All subsequent elements are shifted to the left
5949 * (subtracts one from their indices). If the array doesn't contain
5950 * such an element, no elements are removed from the array.
5951 * <p>
5952 * This method returns a new array with the same elements of the input
5953 * array except the first occurrence of the specified element. The component
5954 * type of the returned array is always the same as that of the input
5955 * array.
5956 * </p>
5957 * <pre>
5958 * ArrayUtils.removeElement(null, true) = null
5959 * ArrayUtils.removeElement([], true) = []
5960 * ArrayUtils.removeElement([true], false) = [true]
5961 * ArrayUtils.removeElement([true, false], false) = [true]
5962 * ArrayUtils.removeElement([true, false, true], true) = [false, true]
5963 * </pre>
5964 *
5965 * @param array the input array, may be {@code null}.
5966 * @param element the element to be removed.
5967 * @return A new array containing the existing elements except the first
5968 * occurrence of the specified element.
5969 * @since 2.1
5970 */
5971 public static boolean[] removeElement(final boolean[] array, final boolean element) {
5972 final int index = indexOf(array, element);
5973 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
5974 }
5975
5976 /**
5977 * Removes the first occurrence of the specified element from the
5978 * specified array. All subsequent elements are shifted to the left
5979 * (subtracts one from their indices). If the array doesn't contain
5980 * such an element, no elements are removed from the array.
5981 * <p>
5982 * This method returns a new array with the same elements of the input
5983 * array except the first occurrence of the specified element. The component
5984 * type of the returned array is always the same as that of the input
5985 * array.
5986 * </p>
5987 * <pre>
5988 * ArrayUtils.removeElement(null, 1) = null
5989 * ArrayUtils.removeElement([], 1) = []
5990 * ArrayUtils.removeElement([1], 0) = [1]
5991 * ArrayUtils.removeElement([1, 0], 0) = [1]
5992 * ArrayUtils.removeElement([1, 0, 1], 1) = [0, 1]
5993 * </pre>
5994 *
5995 * @param array the input array, may be {@code null}.
5996 * @param element the element to be removed.
5997 * @return A new array containing the existing elements except the first
5998 * occurrence of the specified element.
5999 * @since 2.1
6000 */
6001 public static byte[] removeElement(final byte[] array, final byte element) {
6002 final int index = indexOf(array, element);
6003 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6004 }
6005
6006 /**
6007 * Removes the first occurrence of the specified element from the
6008 * specified array. All subsequent elements are shifted to the left
6009 * (subtracts one from their indices). If the array doesn't contain
6010 * such an element, no elements are removed from the array.
6011 * <p>
6012 * This method returns a new array with the same elements of the input
6013 * array except the first occurrence of the specified element. The component
6014 * type of the returned array is always the same as that of the input
6015 * array.
6016 * </p>
6017 * <pre>
6018 * ArrayUtils.removeElement(null, 'a') = null
6019 * ArrayUtils.removeElement([], 'a') = []
6020 * ArrayUtils.removeElement(['a'], 'b') = ['a']
6021 * ArrayUtils.removeElement(['a', 'b'], 'a') = ['b']
6022 * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
6023 * </pre>
6024 *
6025 * @param array the input array, may be {@code null}.
6026 * @param element the element to be removed.
6027 * @return A new array containing the existing elements except the first
6028 * occurrence of the specified element.
6029 * @since 2.1
6030 */
6031 public static char[] removeElement(final char[] array, final char element) {
6032 final int index = indexOf(array, element);
6033 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6034 }
6035
6036 /**
6037 * Removes the first occurrence of the specified element from the
6038 * specified array. All subsequent elements are shifted to the left
6039 * (subtracts one from their indices). If the array doesn't contain
6040 * such an element, no elements are removed from the array.
6041 * <p>
6042 * This method returns a new array with the same elements of the input
6043 * array except the first occurrence of the specified element. The component
6044 * type of the returned array is always the same as that of the input
6045 * array.
6046 * </p>
6047 * <pre>
6048 * ArrayUtils.removeElement(null, 1.1) = null
6049 * ArrayUtils.removeElement([], 1.1) = []
6050 * ArrayUtils.removeElement([1.1], 1.2) = [1.1]
6051 * ArrayUtils.removeElement([1.1, 2.3], 1.1) = [2.3]
6052 * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
6053 * </pre>
6054 *
6055 * @param array the input array, may be {@code null}.
6056 * @param element the element to be removed.
6057 * @return A new array containing the existing elements except the first
6058 * occurrence of the specified element.
6059 * @since 2.1
6060 */
6061 public static double[] removeElement(final double[] array, final double element) {
6062 final int index = indexOf(array, element);
6063 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6064 }
6065
6066 /**
6067 * Removes the first occurrence of the specified element from the
6068 * specified array. All subsequent elements are shifted to the left
6069 * (subtracts one from their indices). If the array doesn't contain
6070 * such an element, no elements are removed from the array.
6071 * <p>
6072 * This method returns a new array with the same elements of the input
6073 * array except the first occurrence of the specified element. The component
6074 * type of the returned array is always the same as that of the input
6075 * array.
6076 * </p>
6077 * <pre>
6078 * ArrayUtils.removeElement(null, 1.1) = null
6079 * ArrayUtils.removeElement([], 1.1) = []
6080 * ArrayUtils.removeElement([1.1], 1.2) = [1.1]
6081 * ArrayUtils.removeElement([1.1, 2.3], 1.1) = [2.3]
6082 * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
6083 * </pre>
6084 *
6085 * @param array the input array, may be {@code null}.
6086 * @param element the element to be removed.
6087 * @return A new array containing the existing elements except the first
6088 * occurrence of the specified element.
6089 * @since 2.1
6090 */
6091 public static float[] removeElement(final float[] array, final float element) {
6092 final int index = indexOf(array, element);
6093 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6094 }
6095
6096 /**
6097 * Removes the first occurrence of the specified element from the
6098 * specified array. All subsequent elements are shifted to the left
6099 * (subtracts one from their indices). If the array doesn't contain
6100 * such an element, no elements are removed from the array.
6101 * <p>
6102 * This method returns a new array with the same elements of the input
6103 * array except the first occurrence of the specified element. The component
6104 * type of the returned array is always the same as that of the input
6105 * array.
6106 * </p>
6107 * <pre>
6108 * ArrayUtils.removeElement(null, 1) = null
6109 * ArrayUtils.removeElement([], 1) = []
6110 * ArrayUtils.removeElement([1], 2) = [1]
6111 * ArrayUtils.removeElement([1, 3], 1) = [3]
6112 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
6113 * </pre>
6114 *
6115 * @param array the input array, may be {@code null}.
6116 * @param element the element to be removed.
6117 * @return A new array containing the existing elements except the first
6118 * occurrence of the specified element.
6119 * @since 2.1
6120 */
6121 public static int[] removeElement(final int[] array, final int element) {
6122 final int index = indexOf(array, element);
6123 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6124 }
6125
6126 /**
6127 * Removes the first occurrence of the specified element from the
6128 * specified array. All subsequent elements are shifted to the left
6129 * (subtracts one from their indices). If the array doesn't contain
6130 * such an element, no elements are removed from the array.
6131 * <p>
6132 * This method returns a new array with the same elements of the input
6133 * array except the first occurrence of the specified element. The component
6134 * type of the returned array is always the same as that of the input
6135 * array.
6136 * </p>
6137 * <pre>
6138 * ArrayUtils.removeElement(null, 1) = null
6139 * ArrayUtils.removeElement([], 1) = []
6140 * ArrayUtils.removeElement([1], 2) = [1]
6141 * ArrayUtils.removeElement([1, 3], 1) = [3]
6142 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
6143 * </pre>
6144 *
6145 * @param array the input array, may be {@code null}.
6146 * @param element the element to be removed.
6147 * @return A new array containing the existing elements except the first
6148 * occurrence of the specified element.
6149 * @since 2.1
6150 */
6151 public static long[] removeElement(final long[] array, final long element) {
6152 final int index = indexOf(array, element);
6153 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6154 }
6155
6156 /**
6157 * Removes the first occurrence of the specified element from the
6158 * specified array. All subsequent elements are shifted to the left
6159 * (subtracts one from their indices). If the array doesn't contain
6160 * such an element, no elements are removed from the array.
6161 * <p>
6162 * This method returns a new array with the same elements of the input
6163 * array except the first occurrence of the specified element. The component
6164 * type of the returned array is always the same as that of the input
6165 * array.
6166 * </p>
6167 * <pre>
6168 * ArrayUtils.removeElement(null, 1) = null
6169 * ArrayUtils.removeElement([], 1) = []
6170 * ArrayUtils.removeElement([1], 2) = [1]
6171 * ArrayUtils.removeElement([1, 3], 1) = [3]
6172 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
6173 * </pre>
6174 *
6175 * @param array the input array, may be {@code null}.
6176 * @param element the element to be removed.
6177 * @return A new array containing the existing elements except the first
6178 * occurrence of the specified element.
6179 * @since 2.1
6180 */
6181 public static short[] removeElement(final short[] array, final short element) {
6182 final int index = indexOf(array, element);
6183 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6184 }
6185
6186 /**
6187 * Removes the first occurrence of the specified element from the
6188 * specified array. All subsequent elements are shifted to the left
6189 * (subtracts one from their indices). If the array doesn't contain
6190 * such an element, no elements are removed from the array.
6191 * <p>
6192 * This method returns a new array with the same elements of the input
6193 * array except the first occurrence of the specified element. The component
6194 * type of the returned array is always the same as that of the input
6195 * array.
6196 * </p>
6197 * <pre>
6198 * ArrayUtils.removeElement(null, "a") = null
6199 * ArrayUtils.removeElement([], "a") = []
6200 * ArrayUtils.removeElement(["a"], "b") = ["a"]
6201 * ArrayUtils.removeElement(["a", "b"], "a") = ["b"]
6202 * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
6203 * </pre>
6204 *
6205 * @param <T> the component type of the array
6206 * @param array the input array, may be {@code null}.
6207 * @param element the element to be removed, may be {@code null}.
6208 * @return A new array containing the existing elements except the first
6209 * occurrence of the specified element.
6210 * @since 2.1
6211 */
6212 public static <T> T[] removeElement(final T[] array, final Object element) {
6213 final int index = indexOf(array, element);
6214 return index == INDEX_NOT_FOUND ? clone(array) : remove(array, index);
6215 }
6216
6217 /**
6218 * Removes occurrences of specified elements, in specified quantities,
6219 * from the specified array. All subsequent elements are shifted left.
6220 * For any element-to-be-removed specified in greater quantities than
6221 * contained in the original array, no change occurs beyond the
6222 * removal of the existing matching items.
6223 * <p>
6224 * This method returns a new array with the same elements of the input
6225 * array except for the earliest-encountered occurrences of the specified
6226 * elements. The component type of the returned array is always the same
6227 * as that of the input array.
6228 * </p>
6229 * <pre>
6230 * ArrayUtils.removeElements(null, true, false) = null
6231 * ArrayUtils.removeElements([], true, false) = []
6232 * ArrayUtils.removeElements([true], false, false) = [true]
6233 * ArrayUtils.removeElements([true, false], true, true) = [false]
6234 * ArrayUtils.removeElements([true, false, true], true) = [false, true]
6235 * ArrayUtils.removeElements([true, false, true], true, true) = [false]
6236 * </pre>
6237 *
6238 * @param array the input array, will not be modified, and may be {@code null}.
6239 * @param values the values to be removed.
6240 * @return A new array containing the existing elements except the
6241 * earliest-encountered occurrences of the specified elements.
6242 * @since 3.0.1
6243 */
6244 public static boolean[] removeElements(final boolean[] array, final boolean... values) {
6245 if (isEmpty(array) || isEmpty(values)) {
6246 return clone(array);
6247 }
6248 final HashMap<Boolean, MutableInt> occurrences = new HashMap<>(2); // only two possible values here
6249 for (final boolean v : values) {
6250 increment(occurrences, Boolean.valueOf(v));
6251 }
6252 final BitSet toRemove = new BitSet();
6253 for (int i = 0; i < array.length; i++) {
6254 final boolean key = array[i];
6255 final MutableInt count = occurrences.get(key);
6256 if (count != null) {
6257 if (count.decrementAndGet() == 0) {
6258 occurrences.remove(key);
6259 }
6260 toRemove.set(i);
6261 }
6262 }
6263 return (boolean[]) removeAt(array, toRemove);
6264 }
6265
6266 /**
6267 * Removes occurrences of specified elements, in specified quantities,
6268 * from the specified array. All subsequent elements are shifted left.
6269 * For any element-to-be-removed specified in greater quantities than
6270 * contained in the original array, no change occurs beyond the
6271 * removal of the existing matching items.
6272 * <p>
6273 * This method returns a new array with the same elements of the input
6274 * array except for the earliest-encountered occurrences of the specified
6275 * elements. The component type of the returned array is always the same
6276 * as that of the input array.
6277 * </p>
6278 * <pre>
6279 * ArrayUtils.removeElements(null, 1, 2) = null
6280 * ArrayUtils.removeElements([], 1, 2) = []
6281 * ArrayUtils.removeElements([1], 2, 3) = [1]
6282 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6283 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6284 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6285 * </pre>
6286 *
6287 * @param array the input array, will not be modified, and may be {@code null}.
6288 * @param values the values to be removed.
6289 * @return A new array containing the existing elements except the
6290 * earliest-encountered occurrences of the specified elements.
6291 * @since 3.0.1
6292 */
6293 public static byte[] removeElements(final byte[] array, final byte... values) {
6294 if (isEmpty(array) || isEmpty(values)) {
6295 return clone(array);
6296 }
6297 final HashMap<Byte, MutableInt> occurrences = new HashMap<>(values.length);
6298 for (final byte v : values) {
6299 increment(occurrences, Byte.valueOf(v));
6300 }
6301 final BitSet toRemove = new BitSet();
6302 for (int i = 0; i < array.length; i++) {
6303 final byte key = array[i];
6304 final MutableInt count = occurrences.get(key);
6305 if (count != null) {
6306 if (count.decrementAndGet() == 0) {
6307 occurrences.remove(key);
6308 }
6309 toRemove.set(i);
6310 }
6311 }
6312 return (byte[]) removeAt(array, toRemove);
6313 }
6314
6315 /**
6316 * Removes occurrences of specified elements, in specified quantities,
6317 * from the specified array. All subsequent elements are shifted left.
6318 * For any element-to-be-removed specified in greater quantities than
6319 * contained in the original array, no change occurs beyond the
6320 * removal of the existing matching items.
6321 * <p>
6322 * This method returns a new array with the same elements of the input
6323 * array except for the earliest-encountered occurrences of the specified
6324 * elements. The component type of the returned array is always the same
6325 * as that of the input array.
6326 * </p>
6327 * <pre>
6328 * ArrayUtils.removeElements(null, 1, 2) = null
6329 * ArrayUtils.removeElements([], 1, 2) = []
6330 * ArrayUtils.removeElements([1], 2, 3) = [1]
6331 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6332 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6333 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6334 * </pre>
6335 *
6336 * @param array the input array, will not be modified, and may be {@code null}.
6337 * @param values the values to be removed.
6338 * @return A new array containing the existing elements except the
6339 * earliest-encountered occurrences of the specified elements.
6340 * @since 3.0.1
6341 */
6342 public static char[] removeElements(final char[] array, final char... values) {
6343 if (isEmpty(array) || isEmpty(values)) {
6344 return clone(array);
6345 }
6346 final HashMap<Character, MutableInt> occurrences = new HashMap<>(values.length);
6347 for (final char v : values) {
6348 increment(occurrences, Character.valueOf(v));
6349 }
6350 final BitSet toRemove = new BitSet();
6351 for (int i = 0; i < array.length; i++) {
6352 final char key = array[i];
6353 final MutableInt count = occurrences.get(key);
6354 if (count != null) {
6355 if (count.decrementAndGet() == 0) {
6356 occurrences.remove(key);
6357 }
6358 toRemove.set(i);
6359 }
6360 }
6361 return (char[]) removeAt(array, toRemove);
6362 }
6363
6364 /**
6365 * Removes occurrences of specified elements, in specified quantities,
6366 * from the specified array. All subsequent elements are shifted left.
6367 * For any element-to-be-removed specified in greater quantities than
6368 * contained in the original array, no change occurs beyond the
6369 * removal of the existing matching items.
6370 * <p>
6371 * This method returns a new array with the same elements of the input
6372 * array except for the earliest-encountered occurrences of the specified
6373 * elements. The component type of the returned array is always the same
6374 * as that of the input array.
6375 * </p>
6376 * <pre>
6377 * ArrayUtils.removeElements(null, 1, 2) = null
6378 * ArrayUtils.removeElements([], 1, 2) = []
6379 * ArrayUtils.removeElements([1], 2, 3) = [1]
6380 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6381 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6382 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6383 * </pre>
6384 *
6385 * @param array the input array, will not be modified, and may be {@code null}.
6386 * @param values the values to be removed.
6387 * @return A new array containing the existing elements except the
6388 * earliest-encountered occurrences of the specified elements.
6389 * @since 3.0.1
6390 */
6391 public static double[] removeElements(final double[] array, final double... values) {
6392 if (isEmpty(array) || isEmpty(values)) {
6393 return clone(array);
6394 }
6395 final HashMap<Double, MutableInt> occurrences = new HashMap<>(values.length);
6396 for (final double v : values) {
6397 increment(occurrences, Double.valueOf(v));
6398 }
6399 final BitSet toRemove = new BitSet();
6400 for (int i = 0; i < array.length; i++) {
6401 final double key = array[i];
6402 final MutableInt count = occurrences.get(key);
6403 if (count != null) {
6404 if (count.decrementAndGet() == 0) {
6405 occurrences.remove(key);
6406 }
6407 toRemove.set(i);
6408 }
6409 }
6410 return (double[]) removeAt(array, toRemove);
6411 }
6412
6413 /**
6414 * Removes occurrences of specified elements, in specified quantities,
6415 * from the specified array. All subsequent elements are shifted left.
6416 * For any element-to-be-removed specified in greater quantities than
6417 * contained in the original array, no change occurs beyond the
6418 * removal of the existing matching items.
6419 * <p>
6420 * This method returns a new array with the same elements of the input
6421 * array except for the earliest-encountered occurrences of the specified
6422 * elements. The component type of the returned array is always the same
6423 * as that of the input array.
6424 * </p>
6425 * <pre>
6426 * ArrayUtils.removeElements(null, 1, 2) = null
6427 * ArrayUtils.removeElements([], 1, 2) = []
6428 * ArrayUtils.removeElements([1], 2, 3) = [1]
6429 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6430 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6431 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6432 * </pre>
6433 *
6434 * @param array the input array, will not be modified, and may be {@code null}.
6435 * @param values the values to be removed.
6436 * @return A new array containing the existing elements except the
6437 * earliest-encountered occurrences of the specified elements.
6438 * @since 3.0.1
6439 */
6440 public static float[] removeElements(final float[] array, final float... values) {
6441 if (isEmpty(array) || isEmpty(values)) {
6442 return clone(array);
6443 }
6444 final HashMap<Float, MutableInt> occurrences = new HashMap<>(values.length);
6445 for (final float v : values) {
6446 increment(occurrences, Float.valueOf(v));
6447 }
6448 final BitSet toRemove = new BitSet();
6449 for (int i = 0; i < array.length; i++) {
6450 final float key = array[i];
6451 final MutableInt count = occurrences.get(key);
6452 if (count != null) {
6453 if (count.decrementAndGet() == 0) {
6454 occurrences.remove(key);
6455 }
6456 toRemove.set(i);
6457 }
6458 }
6459 return (float[]) removeAt(array, toRemove);
6460 }
6461
6462 /**
6463 * Removes occurrences of specified elements, in specified quantities,
6464 * from the specified array. All subsequent elements are shifted left.
6465 * For any element-to-be-removed specified in greater quantities than
6466 * contained in the original array, no change occurs beyond the
6467 * removal of the existing matching items.
6468 * <p>
6469 * This method returns a new array with the same elements of the input
6470 * array except for the earliest-encountered occurrences of the specified
6471 * elements. The component type of the returned array is always the same
6472 * as that of the input array.
6473 * </p>
6474 * <pre>
6475 * ArrayUtils.removeElements(null, 1, 2) = null
6476 * ArrayUtils.removeElements([], 1, 2) = []
6477 * ArrayUtils.removeElements([1], 2, 3) = [1]
6478 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6479 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6480 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6481 * </pre>
6482 *
6483 * @param array the input array, will not be modified, and may be {@code null}.
6484 * @param values the values to be removed.
6485 * @return A new array containing the existing elements except the
6486 * earliest-encountered occurrences of the specified elements.
6487 * @since 3.0.1
6488 */
6489 public static int[] removeElements(final int[] array, final int... values) {
6490 if (isEmpty(array) || isEmpty(values)) {
6491 return clone(array);
6492 }
6493 final HashMap<Integer, MutableInt> occurrences = new HashMap<>(values.length);
6494 for (final int v : values) {
6495 increment(occurrences, Integer.valueOf(v));
6496 }
6497 final BitSet toRemove = new BitSet();
6498 for (int i = 0; i < array.length; i++) {
6499 final int key = array[i];
6500 final MutableInt count = occurrences.get(key);
6501 if (count != null) {
6502 if (count.decrementAndGet() == 0) {
6503 occurrences.remove(key);
6504 }
6505 toRemove.set(i);
6506 }
6507 }
6508 return (int[]) removeAt(array, toRemove);
6509 }
6510
6511 /**
6512 * Removes occurrences of specified elements, in specified quantities,
6513 * from the specified array. All subsequent elements are shifted left.
6514 * For any element-to-be-removed specified in greater quantities than
6515 * contained in the original array, no change occurs beyond the
6516 * removal of the existing matching items.
6517 * <p>
6518 * This method returns a new array with the same elements of the input
6519 * array except for the earliest-encountered occurrences of the specified
6520 * elements. The component type of the returned array is always the same
6521 * as that of the input array.
6522 * </p>
6523 * <pre>
6524 * ArrayUtils.removeElements(null, 1, 2) = null
6525 * ArrayUtils.removeElements([], 1, 2) = []
6526 * ArrayUtils.removeElements([1], 2, 3) = [1]
6527 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6528 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6529 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6530 * </pre>
6531 *
6532 * @param array the input array, will not be modified, and may be {@code null}.
6533 * @param values the values to be removed.
6534 * @return A new array containing the existing elements except the
6535 * earliest-encountered occurrences of the specified elements.
6536 * @since 3.0.1
6537 */
6538 public static long[] removeElements(final long[] array, final long... values) {
6539 if (isEmpty(array) || isEmpty(values)) {
6540 return clone(array);
6541 }
6542 final HashMap<Long, MutableInt> occurrences = new HashMap<>(values.length);
6543 for (final long v : values) {
6544 increment(occurrences, Long.valueOf(v));
6545 }
6546 final BitSet toRemove = new BitSet();
6547 for (int i = 0; i < array.length; i++) {
6548 final long key = array[i];
6549 final MutableInt count = occurrences.get(key);
6550 if (count != null) {
6551 if (count.decrementAndGet() == 0) {
6552 occurrences.remove(key);
6553 }
6554 toRemove.set(i);
6555 }
6556 }
6557 return (long[]) removeAt(array, toRemove);
6558 }
6559
6560 /**
6561 * Removes occurrences of specified elements, in specified quantities,
6562 * from the specified array. All subsequent elements are shifted left.
6563 * For any element-to-be-removed specified in greater quantities than
6564 * contained in the original array, no change occurs beyond the
6565 * removal of the existing matching items.
6566 * <p>
6567 * This method returns a new array with the same elements of the input
6568 * array except for the earliest-encountered occurrences of the specified
6569 * elements. The component type of the returned array is always the same
6570 * as that of the input array.
6571 * </p>
6572 * <pre>
6573 * ArrayUtils.removeElements(null, 1, 2) = null
6574 * ArrayUtils.removeElements([], 1, 2) = []
6575 * ArrayUtils.removeElements([1], 2, 3) = [1]
6576 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
6577 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
6578 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
6579 * </pre>
6580 *
6581 * @param array the input array, will not be modified, and may be {@code null}.
6582 * @param values the values to be removed.
6583 * @return A new array containing the existing elements except the
6584 * earliest-encountered occurrences of the specified elements.
6585 * @since 3.0.1
6586 */
6587 public static short[] removeElements(final short[] array, final short... values) {
6588 if (isEmpty(array) || isEmpty(values)) {
6589 return clone(array);
6590 }
6591 final HashMap<Short, MutableInt> occurrences = new HashMap<>(values.length);
6592 for (final short v : values) {
6593 increment(occurrences, Short.valueOf(v));
6594 }
6595 final BitSet toRemove = new BitSet();
6596 for (int i = 0; i < array.length; i++) {
6597 final short key = array[i];
6598 final MutableInt count = occurrences.get(key);
6599 if (count != null) {
6600 if (count.decrementAndGet() == 0) {
6601 occurrences.remove(key);
6602 }
6603 toRemove.set(i);
6604 }
6605 }
6606 return (short[]) removeAt(array, toRemove);
6607 }
6608
6609 /**
6610 * Removes occurrences of specified elements, in specified quantities,
6611 * from the specified array. All subsequent elements are shifted left.
6612 * For any element-to-be-removed specified in greater quantities than
6613 * contained in the original array, no change occurs beyond the
6614 * removal of the existing matching items.
6615 * <p>
6616 * This method returns a new array with the same elements of the input
6617 * array except for the earliest-encountered occurrences of the specified
6618 * elements. The component type of the returned array is always the same
6619 * as that of the input array.
6620 * </p>
6621 * <pre>
6622 * ArrayUtils.removeElements(null, "a", "b") = null
6623 * ArrayUtils.removeElements([], "a", "b") = []
6624 * ArrayUtils.removeElements(["a"], "b", "c") = ["a"]
6625 * ArrayUtils.removeElements(["a", "b"], "a", "c") = ["b"]
6626 * ArrayUtils.removeElements(["a", "b", "a"], "a") = ["b", "a"]
6627 * ArrayUtils.removeElements(["a", "b", "a"], "a", "a") = ["b"]
6628 * </pre>
6629 *
6630 * @param <T> the component type of the array
6631 * @param array the input array, will not be modified, and may be {@code null}.
6632 * @param values the values to be removed.
6633 * @return A new array containing the existing elements except the
6634 * earliest-encountered occurrences of the specified elements.
6635 * @since 3.0.1
6636 */
6637 @SafeVarargs
6638 public static <T> T[] removeElements(final T[] array, final T... values) {
6639 if (isEmpty(array) || isEmpty(values)) {
6640 return clone(array);
6641 }
6642 final HashMap<T, MutableInt> occurrences = new HashMap<>(values.length);
6643 for (final T v : values) {
6644 increment(occurrences, v);
6645 }
6646 final BitSet toRemove = new BitSet();
6647 for (int i = 0; i < array.length; i++) {
6648 final T key = array[i];
6649 final MutableInt count = occurrences.get(key);
6650 if (count != null) {
6651 if (count.decrementAndGet() == 0) {
6652 occurrences.remove(key);
6653 }
6654 toRemove.set(i);
6655 }
6656 }
6657 @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
6658 final T[] result = (T[]) removeAt(array, toRemove);
6659 return result;
6660 }
6661
6662 /**
6663 * Reverses the order of the given array.
6664 * <p>
6665 * This method does nothing for a {@code null} input array.
6666 * </p>
6667 *
6668 * @param array the array to reverse, may be {@code null}.
6669 */
6670 public static void reverse(final boolean[] array) {
6671 if (array != null) {
6672 reverse(array, 0, array.length);
6673 }
6674 }
6675
6676 /**
6677 * Reverses the order of the given array in the given range.
6678 * <p>
6679 * This method does nothing for a {@code null} input array.
6680 * </p>
6681 *
6682 * @param array
6683 * the array to reverse, may be {@code null}.
6684 * @param startIndexInclusive
6685 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6686 * change.
6687 * @param endIndexExclusive
6688 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6689 * change. Overvalue (>array.length) is demoted to array length.
6690 * @since 3.2
6691 */
6692 public static void reverse(final boolean[] array, final int startIndexInclusive, final int endIndexExclusive) {
6693 if (array == null) {
6694 return;
6695 }
6696 int i = Math.max(startIndexInclusive, 0);
6697 int j = Math.min(array.length, endIndexExclusive) - 1;
6698 boolean tmp;
6699 while (j > i) {
6700 tmp = array[j];
6701 array[j] = array[i];
6702 array[i] = tmp;
6703 j--;
6704 i++;
6705 }
6706 }
6707
6708 /**
6709 * Reverses the order of the given array.
6710 * <p>
6711 * This method does nothing for a {@code null} input array.
6712 * </p>
6713 *
6714 * @param array the array to reverse, may be {@code null}.
6715 */
6716 public static void reverse(final byte[] array) {
6717 if (array != null) {
6718 reverse(array, 0, array.length);
6719 }
6720 }
6721
6722 /**
6723 * Reverses the order of the given array in the given range.
6724 * <p>
6725 * This method does nothing for a {@code null} input array.
6726 * </p>
6727 *
6728 * @param array the array to reverse, may be {@code null}.
6729 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no change.
6730 * @param endIndexExclusive elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no change. Overvalue
6731 * (>array.length) is demoted to array length.
6732 * @since 3.2
6733 */
6734 public static void reverse(final byte[] array, final int startIndexInclusive, final int endIndexExclusive) {
6735 if (array == null) {
6736 return;
6737 }
6738 int i = Math.max(startIndexInclusive, 0);
6739 int j = Math.min(array.length, endIndexExclusive) - 1;
6740 byte tmp;
6741 while (j > i) {
6742 tmp = array[j];
6743 array[j] = array[i];
6744 array[i] = tmp;
6745 j--;
6746 i++;
6747 }
6748 }
6749
6750 /**
6751 * Reverses the order of the given array.
6752 * <p>
6753 * This method does nothing for a {@code null} input array.
6754 * </p>
6755 *
6756 * @param array the array to reverse, may be {@code null}.
6757 */
6758 public static void reverse(final char[] array) {
6759 if (array != null) {
6760 reverse(array, 0, array.length);
6761 }
6762 }
6763
6764 /**
6765 * Reverses the order of the given array in the given range.
6766 * <p>
6767 * This method does nothing for a {@code null} input array.
6768 * </p>
6769 *
6770 * @param array the array to reverse, may be {@code null}.
6771 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no change.
6772 * @param endIndexExclusive elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no change. Overvalue
6773 * (>array.length) is demoted to array length.
6774 * @since 3.2
6775 */
6776 public static void reverse(final char[] array, final int startIndexInclusive, final int endIndexExclusive) {
6777 if (array == null) {
6778 return;
6779 }
6780 int i = Math.max(startIndexInclusive, 0);
6781 int j = Math.min(array.length, endIndexExclusive) - 1;
6782 char tmp;
6783 while (j > i) {
6784 tmp = array[j];
6785 array[j] = array[i];
6786 array[i] = tmp;
6787 j--;
6788 i++;
6789 }
6790 }
6791
6792 /**
6793 * Reverses the order of the given array.
6794 * <p>
6795 * This method does nothing for a {@code null} input array.
6796 * </p>
6797 *
6798 * @param array the array to reverse, may be {@code null}
6799 */
6800 public static void reverse(final double[] array) {
6801 if (array != null) {
6802 reverse(array, 0, array.length);
6803 }
6804 }
6805
6806 /**
6807 * Reverses the order of the given array in the given range.
6808 * <p>
6809 * This method does nothing for a {@code null} input array.
6810 * </p>
6811 *
6812 * @param array the array to reverse, may be {@code null}.
6813 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no change.
6814 * @param endIndexExclusive elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no change. Overvalue
6815 * (>array.length) is demoted to array length.
6816 * @since 3.2
6817 */
6818 public static void reverse(final double[] array, final int startIndexInclusive, final int endIndexExclusive) {
6819 if (array == null) {
6820 return;
6821 }
6822 int i = Math.max(startIndexInclusive, 0);
6823 int j = Math.min(array.length, endIndexExclusive) - 1;
6824 double tmp;
6825 while (j > i) {
6826 tmp = array[j];
6827 array[j] = array[i];
6828 array[i] = tmp;
6829 j--;
6830 i++;
6831 }
6832 }
6833
6834 /**
6835 * Reverses the order of the given array.
6836 * <p>
6837 * This method does nothing for a {@code null} input array.
6838 * </p>
6839 *
6840 * @param array the array to reverse, may be {@code null}.
6841 */
6842 public static void reverse(final float[] array) {
6843 if (array != null) {
6844 reverse(array, 0, array.length);
6845 }
6846 }
6847
6848 /**
6849 * Reverses the order of the given array in the given range.
6850 * <p>
6851 * This method does nothing for a {@code null} input array.
6852 * </p>
6853 *
6854 * @param array the array to reverse, may be {@code null}.
6855 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no change.
6856 * @param endIndexExclusive elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no change. Overvalue
6857 * (>array.length) is demoted to array length.
6858 * @since 3.2
6859 */
6860 public static void reverse(final float[] array, final int startIndexInclusive, final int endIndexExclusive) {
6861 if (array == null) {
6862 return;
6863 }
6864 int i = Math.max(startIndexInclusive, 0);
6865 int j = Math.min(array.length, endIndexExclusive) - 1;
6866 float tmp;
6867 while (j > i) {
6868 tmp = array[j];
6869 array[j] = array[i];
6870 array[i] = tmp;
6871 j--;
6872 i++;
6873 }
6874 }
6875
6876 /**
6877 * Reverses the order of the given array.
6878 * <p>
6879 * This method does nothing for a {@code null} input array.
6880 * </p>
6881 *
6882 * @param array the array to reverse, may be {@code null}.
6883 */
6884 public static void reverse(final int[] array) {
6885 if (array != null) {
6886 reverse(array, 0, array.length);
6887 }
6888 }
6889
6890 /**
6891 * Reverses the order of the given array in the given range.
6892 * <p>
6893 * This method does nothing for a {@code null} input array.
6894 * </p>
6895 *
6896 * @param array
6897 * the array to reverse, may be {@code null}.
6898 * @param startIndexInclusive
6899 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6900 * change.
6901 * @param endIndexExclusive
6902 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6903 * change. Overvalue (>array.length) is demoted to array length.
6904 * @since 3.2
6905 */
6906 public static void reverse(final int[] array, final int startIndexInclusive, final int endIndexExclusive) {
6907 if (array == null) {
6908 return;
6909 }
6910 int i = Math.max(startIndexInclusive, 0);
6911 int j = Math.min(array.length, endIndexExclusive) - 1;
6912 int tmp;
6913 while (j > i) {
6914 tmp = array[j];
6915 array[j] = array[i];
6916 array[i] = tmp;
6917 j--;
6918 i++;
6919 }
6920 }
6921
6922 /**
6923 * Reverses the order of the given array.
6924 * <p>
6925 * This method does nothing for a {@code null} input array.
6926 * </p>
6927 *
6928 * @param array the array to reverse, may be {@code null}.
6929 */
6930 public static void reverse(final long[] array) {
6931 if (array != null) {
6932 reverse(array, 0, array.length);
6933 }
6934 }
6935
6936 /**
6937 * Reverses the order of the given array in the given range.
6938 * <p>
6939 * This method does nothing for a {@code null} input array.
6940 * </p>
6941 *
6942 * @param array
6943 * the array to reverse, may be {@code null}.
6944 * @param startIndexInclusive
6945 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
6946 * change.
6947 * @param endIndexExclusive
6948 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
6949 * change. Overvalue (>array.length) is demoted to array length.
6950 * @since 3.2
6951 */
6952 public static void reverse(final long[] array, final int startIndexInclusive, final int endIndexExclusive) {
6953 if (array == null) {
6954 return;
6955 }
6956 int i = Math.max(startIndexInclusive, 0);
6957 int j = Math.min(array.length, endIndexExclusive) - 1;
6958 long tmp;
6959 while (j > i) {
6960 tmp = array[j];
6961 array[j] = array[i];
6962 array[i] = tmp;
6963 j--;
6964 i++;
6965 }
6966 }
6967
6968 /**
6969 * Reverses the order of the given array.
6970 * <p>
6971 * There is no special handling for multi-dimensional arrays.
6972 * </p>
6973 * <p>
6974 * This method does nothing for a {@code null} input array.
6975 * </p>
6976 *
6977 * @param array the array to reverse, may be {@code null}.
6978 */
6979 public static void reverse(final Object[] array) {
6980 if (array != null) {
6981 reverse(array, 0, array.length);
6982 }
6983 }
6984
6985 /**
6986 * Reverses the order of the given array in the given range.
6987 * <p>
6988 * This method does nothing for a {@code null} input array.
6989 * </p>
6990 *
6991 * @param array
6992 * the array to reverse, may be {@code null}.
6993 * @param startIndexInclusive
6994 * the starting index. Under value (<0) is promoted to 0, over value (>array.length) results in no
6995 * change.
6996 * @param endIndexExclusive
6997 * elements up to endIndex-1 are reversed in the array. Under value (< start index) results in no
6998 * change. Over value (>array.length) is demoted to array length.
6999 * @since 3.2
7000 */
7001 public static void reverse(final Object[] array, final int startIndexInclusive, final int endIndexExclusive) {
7002 if (array == null) {
7003 return;
7004 }
7005 int i = Math.max(startIndexInclusive, 0);
7006 int j = Math.min(array.length, endIndexExclusive) - 1;
7007 Object tmp;
7008 while (j > i) {
7009 tmp = array[j];
7010 array[j] = array[i];
7011 array[i] = tmp;
7012 j--;
7013 i++;
7014 }
7015 }
7016
7017 /**
7018 * Reverses the order of the given array.
7019 * <p>
7020 * This method does nothing for a {@code null} input array.
7021 * </p>
7022 *
7023 * @param array the array to reverse, may be {@code null}.
7024 */
7025 public static void reverse(final short[] array) {
7026 if (array != null) {
7027 reverse(array, 0, array.length);
7028 }
7029 }
7030
7031 /**
7032 * Reverses the order of the given array in the given range.
7033 * <p>
7034 * This method does nothing for a {@code null} input array.
7035 * </p>
7036 *
7037 * @param array
7038 * the array to reverse, may be {@code null}.
7039 * @param startIndexInclusive
7040 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7041 * change.
7042 * @param endIndexExclusive
7043 * elements up to endIndex-1 are reversed in the array. Undervalue (< start index) results in no
7044 * change. Overvalue (>array.length) is demoted to array length.
7045 * @since 3.2
7046 */
7047 public static void reverse(final short[] array, final int startIndexInclusive, final int endIndexExclusive) {
7048 if (array == null) {
7049 return;
7050 }
7051 int i = Math.max(startIndexInclusive, 0);
7052 int j = Math.min(array.length, endIndexExclusive) - 1;
7053 short tmp;
7054 while (j > i) {
7055 tmp = array[j];
7056 array[j] = array[i];
7057 array[i] = tmp;
7058 j--;
7059 i++;
7060 }
7061 }
7062
7063 /**
7064 * Sets all elements of the specified array, using the provided generator supplier to compute each element.
7065 * <p>
7066 * If the generator supplier throws an exception, it is relayed to the caller and the array is left in an indeterminate
7067 * state.
7068 * </p>
7069 *
7070 * @param <T> type of elements of the array, may be {@code null}.
7071 * @param array array to be initialized, may be {@code null}.
7072 * @param generator a function accepting an index and producing the desired value for that position.
7073 * @return the input array
7074 * @since 3.13.0
7075 */
7076 public static <T> T[] setAll(final T[] array, final IntFunction<? extends T> generator) {
7077 if (array != null && generator != null) {
7078 Arrays.setAll(array, generator);
7079 }
7080 return array;
7081 }
7082
7083 /**
7084 * Sets all elements of the specified array, using the provided generator supplier to compute each element.
7085 * <p>
7086 * If the generator supplier throws an exception, it is relayed to the caller and the array is left in an indeterminate
7087 * state.
7088 * </p>
7089 *
7090 * @param <T> type of elements of the array, may be {@code null}.
7091 * @param array array to be initialized, may be {@code null}.
7092 * @param generator a function accepting an index and producing the desired value for that position.
7093 * @return the input array
7094 * @since 3.13.0
7095 */
7096 public static <T> T[] setAll(final T[] array, final Supplier<? extends T> generator) {
7097 if (array != null && generator != null) {
7098 for (int i = 0; i < array.length; i++) {
7099 array[i] = generator.get();
7100 }
7101 }
7102 return array;
7103 }
7104
7105 /**
7106 * Shifts the order of the given boolean array.
7107 *
7108 * <p>There is no special handling for multi-dimensional arrays. This method
7109 * does nothing for {@code null} or empty input arrays.</p>
7110 *
7111 * @param array the array to shift, may be {@code null}.
7112 * @param offset
7113 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7114 * rotate, than the effective offset is modulo the number of elements to rotate.
7115 * @since 3.5
7116 */
7117 public static void shift(final boolean[] array, final int offset) {
7118 if (array != null) {
7119 shift(array, 0, array.length, offset);
7120 }
7121 }
7122
7123 /**
7124 * Shifts the order of a series of elements in the given boolean array.
7125 *
7126 * <p>There is no special handling for multi-dimensional arrays. This method
7127 * does nothing for {@code null} or empty input arrays.</p>
7128 *
7129 * @param array
7130 * the array to shift, may be {@code null}.
7131 * @param startIndexInclusive
7132 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7133 * change.
7134 * @param endIndexExclusive
7135 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7136 * change. Overvalue (>array.length) is demoted to array length.
7137 * @param offset
7138 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7139 * rotate, than the effective offset is modulo the number of elements to rotate.
7140 * @since 3.5
7141 */
7142 public static void shift(final boolean[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7143 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7144 return;
7145 }
7146 startIndexInclusive = max0(startIndexInclusive);
7147 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7148 int n = endIndexExclusive - startIndexInclusive;
7149 if (n <= 1) {
7150 return;
7151 }
7152 offset %= n;
7153 if (offset < 0) {
7154 offset += n;
7155 }
7156 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7157 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7158 while (n > 1 && offset > 0) {
7159 final int nOffset = n - offset;
7160 if (offset > nOffset) {
7161 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7162 n = offset;
7163 offset -= nOffset;
7164 } else if (offset < nOffset) {
7165 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7166 startIndexInclusive += offset;
7167 n = nOffset;
7168 } else {
7169 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7170 break;
7171 }
7172 }
7173 }
7174
7175 /**
7176 * Shifts the order of the given byte array.
7177 *
7178 * <p>There is no special handling for multi-dimensional arrays. This method
7179 * does nothing for {@code null} or empty input arrays.</p>
7180 *
7181 * @param array the array to shift, may be {@code null}.
7182 * @param offset
7183 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7184 * rotate, than the effective offset is modulo the number of elements to rotate.
7185 * @since 3.5
7186 */
7187 public static void shift(final byte[] array, final int offset) {
7188 if (array != null) {
7189 shift(array, 0, array.length, offset);
7190 }
7191 }
7192
7193 /**
7194 * Shifts the order of a series of elements in the given byte array.
7195 *
7196 * <p>There is no special handling for multi-dimensional arrays. This method
7197 * does nothing for {@code null} or empty input arrays.</p>
7198 *
7199 * @param array
7200 * the array to shift, may be {@code null}.
7201 * @param startIndexInclusive
7202 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7203 * change.
7204 * @param endIndexExclusive
7205 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7206 * change. Overvalue (>array.length) is demoted to array length.
7207 * @param offset
7208 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7209 * rotate, than the effective offset is modulo the number of elements to rotate.
7210 * @since 3.5
7211 */
7212 public static void shift(final byte[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7213 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7214 return;
7215 }
7216 startIndexInclusive = max0(startIndexInclusive);
7217 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7218 int n = endIndexExclusive - startIndexInclusive;
7219 if (n <= 1) {
7220 return;
7221 }
7222 offset %= n;
7223 if (offset < 0) {
7224 offset += n;
7225 }
7226 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7227 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7228 while (n > 1 && offset > 0) {
7229 final int nOffset = n - offset;
7230 if (offset > nOffset) {
7231 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7232 n = offset;
7233 offset -= nOffset;
7234 } else if (offset < nOffset) {
7235 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7236 startIndexInclusive += offset;
7237 n = nOffset;
7238 } else {
7239 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7240 break;
7241 }
7242 }
7243 }
7244
7245 /**
7246 * Shifts the order of the given char array.
7247 *
7248 * <p>There is no special handling for multi-dimensional arrays. This method
7249 * does nothing for {@code null} or empty input arrays.</p>
7250 *
7251 * @param array the array to shift, may be {@code null}.
7252 * @param offset
7253 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7254 * rotate, than the effective offset is modulo the number of elements to rotate.
7255 * @since 3.5
7256 */
7257 public static void shift(final char[] array, final int offset) {
7258 if (array != null) {
7259 shift(array, 0, array.length, offset);
7260 }
7261 }
7262
7263 /**
7264 * Shifts the order of a series of elements in the given char array.
7265 *
7266 * <p>There is no special handling for multi-dimensional arrays. This method
7267 * does nothing for {@code null} or empty input arrays.</p>
7268 *
7269 * @param array
7270 * the array to shift, may be {@code null}.
7271 * @param startIndexInclusive
7272 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7273 * change.
7274 * @param endIndexExclusive
7275 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7276 * change. Overvalue (>array.length) is demoted to array length.
7277 * @param offset
7278 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7279 * rotate, than the effective offset is modulo the number of elements to rotate.
7280 * @since 3.5
7281 */
7282 public static void shift(final char[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7283 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7284 return;
7285 }
7286 startIndexInclusive = max0(startIndexInclusive);
7287 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7288 int n = endIndexExclusive - startIndexInclusive;
7289 if (n <= 1) {
7290 return;
7291 }
7292 offset %= n;
7293 if (offset < 0) {
7294 offset += n;
7295 }
7296 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7297 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7298 while (n > 1 && offset > 0) {
7299 final int nOffset = n - offset;
7300 if (offset > nOffset) {
7301 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7302 n = offset;
7303 offset -= nOffset;
7304 } else if (offset < nOffset) {
7305 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7306 startIndexInclusive += offset;
7307 n = nOffset;
7308 } else {
7309 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7310 break;
7311 }
7312 }
7313 }
7314
7315 /**
7316 * Shifts the order of the given double array.
7317 *
7318 * <p>There is no special handling for multi-dimensional arrays. This method
7319 * does nothing for {@code null} or empty input arrays.</p>
7320 *
7321 * @param array the array to shift, may be {@code null}.
7322 * @param offset
7323 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7324 * rotate, than the effective offset is modulo the number of elements to rotate.
7325 * @since 3.5
7326 */
7327 public static void shift(final double[] array, final int offset) {
7328 if (array != null) {
7329 shift(array, 0, array.length, offset);
7330 }
7331 }
7332
7333 /**
7334 * Shifts the order of a series of elements in the given double array.
7335 *
7336 * <p>There is no special handling for multi-dimensional arrays. This method
7337 * does nothing for {@code null} or empty input arrays.</p>
7338 *
7339 * @param array
7340 * the array to shift, may be {@code null}.
7341 * @param startIndexInclusive
7342 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7343 * change.
7344 * @param endIndexExclusive
7345 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7346 * change. Overvalue (>array.length) is demoted to array length.
7347 * @param offset
7348 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7349 * rotate, than the effective offset is modulo the number of elements to rotate.
7350 * @since 3.5
7351 */
7352 public static void shift(final double[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7353 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7354 return;
7355 }
7356 startIndexInclusive = max0(startIndexInclusive);
7357 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7358 int n = endIndexExclusive - startIndexInclusive;
7359 if (n <= 1) {
7360 return;
7361 }
7362 offset %= n;
7363 if (offset < 0) {
7364 offset += n;
7365 }
7366 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7367 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7368 while (n > 1 && offset > 0) {
7369 final int nOffset = n - offset;
7370 if (offset > nOffset) {
7371 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7372 n = offset;
7373 offset -= nOffset;
7374 } else if (offset < nOffset) {
7375 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7376 startIndexInclusive += offset;
7377 n = nOffset;
7378 } else {
7379 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7380 break;
7381 }
7382 }
7383 }
7384
7385 /**
7386 * Shifts the order of the given float array.
7387 *
7388 * <p>There is no special handling for multi-dimensional arrays. This method
7389 * does nothing for {@code null} or empty input arrays.</p>
7390 *
7391 * @param array the array to shift, may be {@code null}.
7392 * @param offset
7393 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7394 * rotate, than the effective offset is modulo the number of elements to rotate.
7395 * @since 3.5
7396 */
7397 public static void shift(final float[] array, final int offset) {
7398 if (array != null) {
7399 shift(array, 0, array.length, offset);
7400 }
7401 }
7402
7403 /**
7404 * Shifts the order of a series of elements in the given float array.
7405 *
7406 * <p>There is no special handling for multi-dimensional arrays. This method
7407 * does nothing for {@code null} or empty input arrays.</p>
7408 *
7409 * @param array
7410 * the array to shift, may be {@code null}.
7411 * @param startIndexInclusive
7412 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7413 * change.
7414 * @param endIndexExclusive
7415 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7416 * change. Overvalue (>array.length) is demoted to array length.
7417 * @param offset
7418 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7419 * rotate, than the effective offset is modulo the number of elements to rotate.
7420 * @since 3.5
7421 */
7422 public static void shift(final float[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7423 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7424 return;
7425 }
7426 startIndexInclusive = max0(startIndexInclusive);
7427 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7428 int n = endIndexExclusive - startIndexInclusive;
7429 if (n <= 1) {
7430 return;
7431 }
7432 offset %= n;
7433 if (offset < 0) {
7434 offset += n;
7435 }
7436 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7437 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7438 while (n > 1 && offset > 0) {
7439 final int nOffset = n - offset;
7440 if (offset > nOffset) {
7441 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7442 n = offset;
7443 offset -= nOffset;
7444 } else if (offset < nOffset) {
7445 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7446 startIndexInclusive += offset;
7447 n = nOffset;
7448 } else {
7449 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7450 break;
7451 }
7452 }
7453 }
7454
7455 /**
7456 * Shifts the order of the given int array.
7457 *
7458 * <p>There is no special handling for multi-dimensional arrays. This method
7459 * does nothing for {@code null} or empty input arrays.</p>
7460 *
7461 * @param array the array to shift, may be {@code null}.
7462 * @param offset
7463 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7464 * rotate, than the effective offset is modulo the number of elements to rotate.
7465 * @since 3.5
7466 */
7467 public static void shift(final int[] array, final int offset) {
7468 if (array != null) {
7469 shift(array, 0, array.length, offset);
7470 }
7471 }
7472
7473 /**
7474 * Shifts the order of a series of elements in the given int array.
7475 *
7476 * <p>There is no special handling for multi-dimensional arrays. This method
7477 * does nothing for {@code null} or empty input arrays.</p>
7478 *
7479 * @param array
7480 * the array to shift, may be {@code null}.
7481 * @param startIndexInclusive
7482 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7483 * change.
7484 * @param endIndexExclusive
7485 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7486 * change. Overvalue (>array.length) is demoted to array length.
7487 * @param offset
7488 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7489 * rotate, than the effective offset is modulo the number of elements to rotate.
7490 * @since 3.5
7491 */
7492 public static void shift(final int[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7493 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7494 return;
7495 }
7496 startIndexInclusive = max0(startIndexInclusive);
7497 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7498 int n = endIndexExclusive - startIndexInclusive;
7499 if (n <= 1) {
7500 return;
7501 }
7502 offset %= n;
7503 if (offset < 0) {
7504 offset += n;
7505 }
7506 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7507 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7508 while (n > 1 && offset > 0) {
7509 final int nOffset = n - offset;
7510 if (offset > nOffset) {
7511 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7512 n = offset;
7513 offset -= nOffset;
7514 } else if (offset < nOffset) {
7515 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7516 startIndexInclusive += offset;
7517 n = nOffset;
7518 } else {
7519 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7520 break;
7521 }
7522 }
7523 }
7524
7525 /**
7526 * Shifts the order of the given long array.
7527 *
7528 * <p>There is no special handling for multi-dimensional arrays. This method
7529 * does nothing for {@code null} or empty input arrays.</p>
7530 *
7531 * @param array the array to shift, may be {@code null}.
7532 * @param offset
7533 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7534 * rotate, than the effective offset is modulo the number of elements to rotate.
7535 * @since 3.5
7536 */
7537 public static void shift(final long[] array, final int offset) {
7538 if (array != null) {
7539 shift(array, 0, array.length, offset);
7540 }
7541 }
7542
7543 /**
7544 * Shifts the order of a series of elements in the given long array.
7545 *
7546 * <p>There is no special handling for multi-dimensional arrays. This method
7547 * does nothing for {@code null} or empty input arrays.</p>
7548 *
7549 * @param array
7550 * the array to shift, may be {@code null}.
7551 * @param startIndexInclusive
7552 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7553 * change.
7554 * @param endIndexExclusive
7555 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7556 * change. Overvalue (>array.length) is demoted to array length.
7557 * @param offset
7558 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7559 * rotate, than the effective offset is modulo the number of elements to rotate.
7560 * @since 3.5
7561 */
7562 public static void shift(final long[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7563 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7564 return;
7565 }
7566 startIndexInclusive = max0(startIndexInclusive);
7567 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7568 int n = endIndexExclusive - startIndexInclusive;
7569 if (n <= 1) {
7570 return;
7571 }
7572 offset %= n;
7573 if (offset < 0) {
7574 offset += n;
7575 }
7576 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7577 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7578 while (n > 1 && offset > 0) {
7579 final int nOffset = n - offset;
7580 if (offset > nOffset) {
7581 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7582 n = offset;
7583 offset -= nOffset;
7584 } else if (offset < nOffset) {
7585 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7586 startIndexInclusive += offset;
7587 n = nOffset;
7588 } else {
7589 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7590 break;
7591 }
7592 }
7593 }
7594
7595 /**
7596 * Shifts the order of the given array.
7597 *
7598 * <p>There is no special handling for multi-dimensional arrays. This method
7599 * does nothing for {@code null} or empty input arrays.</p>
7600 *
7601 * @param array the array to shift, may be {@code null}.
7602 * @param offset
7603 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7604 * rotate, than the effective offset is modulo the number of elements to rotate.
7605 * @since 3.5
7606 */
7607 public static void shift(final Object[] array, final int offset) {
7608 if (array != null) {
7609 shift(array, 0, array.length, offset);
7610 }
7611 }
7612
7613 /**
7614 * Shifts the order of a series of elements in the given array.
7615 *
7616 * <p>There is no special handling for multi-dimensional arrays. This method
7617 * does nothing for {@code null} or empty input arrays.</p>
7618 *
7619 * @param array
7620 * the array to shift, may be {@code null}.
7621 * @param startIndexInclusive
7622 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7623 * change.
7624 * @param endIndexExclusive
7625 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7626 * change. Overvalue (>array.length) is demoted to array length.
7627 * @param offset
7628 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7629 * rotate, than the effective offset is modulo the number of elements to rotate.
7630 * @since 3.5
7631 */
7632 public static void shift(final Object[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7633 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7634 return;
7635 }
7636 startIndexInclusive = max0(startIndexInclusive);
7637 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7638 int n = endIndexExclusive - startIndexInclusive;
7639 if (n <= 1) {
7640 return;
7641 }
7642 offset %= n;
7643 if (offset < 0) {
7644 offset += n;
7645 }
7646 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7647 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7648 while (n > 1 && offset > 0) {
7649 final int nOffset = n - offset;
7650 if (offset > nOffset) {
7651 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7652 n = offset;
7653 offset -= nOffset;
7654 } else if (offset < nOffset) {
7655 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7656 startIndexInclusive += offset;
7657 n = nOffset;
7658 } else {
7659 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7660 break;
7661 }
7662 }
7663 }
7664
7665 /**
7666 * Shifts the order of the given short array.
7667 *
7668 * <p>There is no special handling for multi-dimensional arrays. This method
7669 * does nothing for {@code null} or empty input arrays.</p>
7670 *
7671 * @param array the array to shift, may be {@code null}.
7672 * @param offset
7673 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7674 * rotate, than the effective offset is modulo the number of elements to rotate.
7675 * @since 3.5
7676 */
7677 public static void shift(final short[] array, final int offset) {
7678 if (array != null) {
7679 shift(array, 0, array.length, offset);
7680 }
7681 }
7682
7683 /**
7684 * Shifts the order of a series of elements in the given short array.
7685 *
7686 * <p>There is no special handling for multi-dimensional arrays. This method
7687 * does nothing for {@code null} or empty input arrays.</p>
7688 *
7689 * @param array
7690 * the array to shift, may be {@code null}.
7691 * @param startIndexInclusive
7692 * the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in no
7693 * change.
7694 * @param endIndexExclusive
7695 * elements up to endIndex-1 are shifted in the array. Undervalue (< start index) results in no
7696 * change. Overvalue (>array.length) is demoted to array length.
7697 * @param offset
7698 * The number of positions to rotate the elements. If the offset is larger than the number of elements to
7699 * rotate, than the effective offset is modulo the number of elements to rotate.
7700 * @since 3.5
7701 */
7702 public static void shift(final short[] array, int startIndexInclusive, int endIndexExclusive, int offset) {
7703 if (array == null || startIndexInclusive >= array.length - 1 || endIndexExclusive <= 0) {
7704 return;
7705 }
7706 startIndexInclusive = max0(startIndexInclusive);
7707 endIndexExclusive = Math.min(endIndexExclusive, array.length);
7708 int n = endIndexExclusive - startIndexInclusive;
7709 if (n <= 1) {
7710 return;
7711 }
7712 offset %= n;
7713 if (offset < 0) {
7714 offset += n;
7715 }
7716 // For algorithm explanations and proof of O(n) time complexity and O(1) space complexity
7717 // see https://beradrian.wordpress.com/2015/04/07/shift-an-array-in-on-in-place/
7718 while (n > 1 && offset > 0) {
7719 final int nOffset = n - offset;
7720 if (offset > nOffset) {
7721 swap(array, startIndexInclusive, startIndexInclusive + n - nOffset, nOffset);
7722 n = offset;
7723 offset -= nOffset;
7724 } else if (offset < nOffset) {
7725 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7726 startIndexInclusive += offset;
7727 n = nOffset;
7728 } else {
7729 swap(array, startIndexInclusive, startIndexInclusive + nOffset, offset);
7730 break;
7731 }
7732 }
7733 }
7734
7735 /**
7736 * 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
7737 * algorithm</a>.
7738 * <p>
7739 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7740 * </p>
7741 * <p>
7742 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7743 * with a {@link SecureRandom} argument.
7744 * </p>
7745 *
7746 * @param array the array to shuffle.
7747 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7748 * @since 3.6
7749 */
7750 public static void shuffle(final boolean[] array) {
7751 shuffle(array, random());
7752 }
7753
7754 /**
7755 * 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
7756 * algorithm</a>.
7757 *
7758 * @param array the array to shuffle, no-op if {@code null}.
7759 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
7760 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7761 * @since 3.6
7762 */
7763 public static void shuffle(final boolean[] array, final Random random) {
7764 if (array != null && random != null) {
7765 for (int i = array.length; i > 1; i--) {
7766 swap(array, i - 1, random.nextInt(i), 1);
7767 }
7768 }
7769 }
7770
7771 /**
7772 * 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
7773 * algorithm</a>.
7774 * <p>
7775 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7776 * </p>
7777 * <p>
7778 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7779 * with a {@link SecureRandom} argument.
7780 * </p>
7781 *
7782 * @param array the array to shuffle.
7783 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7784 * @since 3.6
7785 */
7786 public static void shuffle(final byte[] array) {
7787 shuffle(array, random());
7788 }
7789
7790 /**
7791 * 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
7792 * algorithm</a>.
7793 *
7794 * @param array the array to shuffle, no-op if {@code null}.
7795 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
7796 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7797 * @since 3.6
7798 */
7799 public static void shuffle(final byte[] array, final Random random) {
7800 if (array != null && random != null) {
7801 for (int i = array.length; i > 1; i--) {
7802 swap(array, i - 1, random.nextInt(i), 1);
7803 }
7804 }
7805 }
7806
7807 /**
7808 * 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
7809 * algorithm</a>.
7810 * <p>
7811 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7812 * </p>
7813 * <p>
7814 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7815 * with a {@link SecureRandom} argument.
7816 * </p>
7817 *
7818 * @param array the array to shuffle.
7819 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7820 * @since 3.6
7821 */
7822 public static void shuffle(final char[] array) {
7823 shuffle(array, random());
7824 }
7825
7826 /**
7827 * 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
7828 * algorithm</a>.
7829 *
7830 * @param array the array to shuffle, no-op if {@code null}.
7831 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
7832 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7833 * @since 3.6
7834 */
7835 public static void shuffle(final char[] array, final Random random) {
7836 if (array != null && random != null) {
7837 for (int i = array.length; i > 1; i--) {
7838 swap(array, i - 1, random.nextInt(i), 1);
7839 }
7840 }
7841 }
7842
7843 /**
7844 * 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
7845 * algorithm</a>.
7846 * <p>
7847 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7848 * </p>
7849 * <p>
7850 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7851 * with a {@link SecureRandom} argument.
7852 * </p>
7853 *
7854 * @param array the array to shuffle.
7855 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7856 * @since 3.6
7857 */
7858 public static void shuffle(final double[] array) {
7859 shuffle(array, random());
7860 }
7861
7862 /**
7863 * 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
7864 * algorithm</a>.
7865 *
7866 * @param array the array to shuffle, no-op if {@code null}.
7867 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
7868 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7869 * @since 3.6
7870 */
7871 public static void shuffle(final double[] array, final Random random) {
7872 if (array != null && random != null) {
7873 for (int i = array.length; i > 1; i--) {
7874 swap(array, i - 1, random.nextInt(i), 1);
7875 }
7876 }
7877 }
7878
7879 /**
7880 * 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
7881 * algorithm</a>.
7882 * <p>
7883 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7884 * </p>
7885 * <p>
7886 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7887 * with a {@link SecureRandom} argument.
7888 * </p>
7889 *
7890 * @param array the array to shuffle.
7891 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7892 * @since 3.6
7893 */
7894 public static void shuffle(final float[] array) {
7895 shuffle(array, random());
7896 }
7897
7898 /**
7899 * 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
7900 * algorithm</a>.
7901 *
7902 * @param array the array to shuffle, no-op if {@code null}.
7903 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
7904 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7905 * @since 3.6
7906 */
7907 public static void shuffle(final float[] array, final Random random) {
7908 if (array != null && random != null) {
7909 for (int i = array.length; i > 1; i--) {
7910 swap(array, i - 1, random.nextInt(i), 1);
7911 }
7912 }
7913 }
7914
7915 /**
7916 * 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
7917 * algorithm</a>.
7918 * <p>
7919 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7920 * </p>
7921 * <p>
7922 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7923 * with a {@link SecureRandom} argument.
7924 * </p>
7925 *
7926 * @param array the array to shuffle.
7927 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7928 * @since 3.6
7929 */
7930 public static void shuffle(final int[] array) {
7931 shuffle(array, random());
7932 }
7933
7934 /**
7935 * 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
7936 * algorithm</a>.
7937 *
7938 * @param array the array to shuffle, no-op if {@code null}.
7939 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
7940 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7941 * @since 3.6
7942 */
7943 public static void shuffle(final int[] array, final Random random) {
7944 if (array != null && random != null) {
7945 for (int i = array.length; i > 1; i--) {
7946 swap(array, i - 1, random.nextInt(i), 1);
7947 }
7948 }
7949 }
7950
7951 /**
7952 * 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
7953 * algorithm</a>.
7954 * <p>
7955 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7956 * </p>
7957 * <p>
7958 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7959 * with a {@link SecureRandom} argument.
7960 * </p>
7961 *
7962 * @param array the array to shuffle.
7963 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7964 * @since 3.6
7965 */
7966 public static void shuffle(final long[] array) {
7967 shuffle(array, random());
7968 }
7969
7970 /**
7971 * 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
7972 * algorithm</a>.
7973 *
7974 * @param array the array to shuffle, no-op if {@code null}.
7975 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
7976 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
7977 * @since 3.6
7978 */
7979 public static void shuffle(final long[] array, final Random random) {
7980 if (array != null && random != null) {
7981 for (int i = array.length; i > 1; i--) {
7982 swap(array, i - 1, random.nextInt(i), 1);
7983 }
7984 }
7985 }
7986
7987 /**
7988 * 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
7989 * algorithm</a>.
7990 * <p>
7991 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
7992 * </p>
7993 * <p>
7994 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
7995 * with a {@link SecureRandom} argument.
7996 * </p>
7997 *
7998 * @param array the array to shuffle.
7999 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
8000 * @since 3.6
8001 */
8002 public static void shuffle(final Object[] array) {
8003 shuffle(array, random());
8004 }
8005
8006 /**
8007 * 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
8008 * algorithm</a>.
8009 *
8010 * @param array the array to shuffle, no-op if {@code null}.
8011 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
8012 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
8013 * @since 3.6
8014 */
8015 public static void shuffle(final Object[] array, final Random random) {
8016 if (array != null && random != null) {
8017 for (int i = array.length; i > 1; i--) {
8018 swap(array, i - 1, random.nextInt(i), 1);
8019 }
8020 }
8021 }
8022
8023 /**
8024 * 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
8025 * algorithm</a>.
8026 * <p>
8027 * This method uses the current {@link ThreadLocalRandom} as its random number generator.
8028 * </p>
8029 * <p>
8030 * Instances of {@link ThreadLocalRandom} are not cryptographically secure. For security-sensitive applications, consider using a {@code shuffle} method
8031 * with a {@link SecureRandom} argument.
8032 * </p>
8033 *
8034 * @param array the array to shuffle.
8035 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
8036 * @since 3.6
8037 */
8038 public static void shuffle(final short[] array) {
8039 shuffle(array, random());
8040 }
8041
8042 /**
8043 * 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
8044 * algorithm</a>.
8045 *
8046 * @param array the array to shuffle, no-op if {@code null}.
8047 * @param random the source of randomness used to permute the elements, no-op if {@code null}.
8048 * @see <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle algorithm</a>
8049 * @since 3.6
8050 */
8051 public static void shuffle(final short[] array, final Random random) {
8052 if (array != null && random != null) {
8053 for (int i = array.length; i > 1; i--) {
8054 swap(array, i - 1, random.nextInt(i), 1);
8055 }
8056 }
8057 }
8058
8059 /**
8060 * Tests whether the given data array starts with an expected array, for example, signature bytes.
8061 * <p>
8062 * If both arrays are null, the method returns true. The method return false when one array is null and the other not.
8063 * </p>
8064 *
8065 * @param data The data to search, maybe larger than the expected data.
8066 * @param expected The expected data to find.
8067 * @return whether a match was found.
8068 * @since 3.18.0
8069 */
8070 public static boolean startsWith(final byte[] data, final byte[] expected) {
8071 if (data == expected) {
8072 return true;
8073 }
8074 if (data == null || expected == null) {
8075 return false;
8076 }
8077 final int dataLen = data.length;
8078 if (expected.length > dataLen) {
8079 return false;
8080 }
8081 if (expected.length == dataLen) {
8082 // delegate to Arrays.equals() which has optimizations on Java > 8
8083 return Arrays.equals(data, expected);
8084 }
8085 // Once we are on Java 9+ we can delegate to Arrays here as well (or not).
8086 for (int i = 0; i < expected.length; i++) {
8087 if (data[i] != expected[i]) {
8088 return false;
8089 }
8090 }
8091 return true;
8092 }
8093
8094 /**
8095 * Produces a new {@code boolean} array containing the elements between the start and end indices.
8096 * <p>
8097 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8098 * </p>
8099 *
8100 * @param array the input array.
8101 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8102 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8103 * (>array.length) is demoted to array length.
8104 * @return a new array containing the elements between the start and end indices.
8105 * @since 2.1
8106 * @see Arrays#copyOfRange(boolean[], int, int)
8107 */
8108 public static boolean[] subarray(final boolean[] array, int startIndexInclusive, int endIndexExclusive) {
8109 if (array == null) {
8110 return null;
8111 }
8112 startIndexInclusive = max0(startIndexInclusive);
8113 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8114 final int newSize = endIndexExclusive - startIndexInclusive;
8115 if (newSize <= 0) {
8116 return EMPTY_BOOLEAN_ARRAY;
8117 }
8118 return arraycopy(array, startIndexInclusive, 0, newSize, boolean[]::new);
8119 }
8120
8121 /**
8122 * Produces a new {@code byte} array containing the elements between the start and end indices.
8123 * <p>
8124 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8125 * </p>
8126 *
8127 * @param array the input array.
8128 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8129 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8130 * (>array.length) is demoted to array length.
8131 * @return a new array containing the elements between the start and end indices.
8132 * @since 2.1
8133 * @see Arrays#copyOfRange(byte[], int, int)
8134 */
8135 public static byte[] subarray(final byte[] array, int startIndexInclusive, int endIndexExclusive) {
8136 if (array == null) {
8137 return null;
8138 }
8139 startIndexInclusive = max0(startIndexInclusive);
8140 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8141 final int newSize = endIndexExclusive - startIndexInclusive;
8142 if (newSize <= 0) {
8143 return EMPTY_BYTE_ARRAY;
8144 }
8145 return arraycopy(array, startIndexInclusive, 0, newSize, byte[]::new);
8146 }
8147
8148 /**
8149 * Produces a new {@code char} array containing the elements between the start and end indices.
8150 * <p>
8151 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8152 * </p>
8153 *
8154 * @param array the input array.
8155 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8156 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8157 * (>array.length) is demoted to array length.
8158 * @return a new array containing the elements between the start and end indices.
8159 * @since 2.1
8160 * @see Arrays#copyOfRange(char[], int, int)
8161 */
8162 public static char[] subarray(final char[] array, int startIndexInclusive, int endIndexExclusive) {
8163 if (array == null) {
8164 return null;
8165 }
8166 startIndexInclusive = max0(startIndexInclusive);
8167 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8168 final int newSize = endIndexExclusive - startIndexInclusive;
8169 if (newSize <= 0) {
8170 return EMPTY_CHAR_ARRAY;
8171 }
8172 return arraycopy(array, startIndexInclusive, 0, newSize, char[]::new);
8173 }
8174
8175 /**
8176 * Produces a new {@code double} array containing the elements between the start and end indices.
8177 * <p>
8178 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8179 * </p>
8180 *
8181 * @param array the input array.
8182 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8183 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8184 * (>array.length) is demoted to array length.
8185 * @return a new array containing the elements between the start and end indices.
8186 * @since 2.1
8187 * @see Arrays#copyOfRange(double[], int, int)
8188 */
8189 public static double[] subarray(final double[] array, int startIndexInclusive, int endIndexExclusive) {
8190 if (array == null) {
8191 return null;
8192 }
8193 startIndexInclusive = max0(startIndexInclusive);
8194 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8195 final int newSize = endIndexExclusive - startIndexInclusive;
8196 if (newSize <= 0) {
8197 return EMPTY_DOUBLE_ARRAY;
8198 }
8199 return arraycopy(array, startIndexInclusive, 0, newSize, double[]::new);
8200 }
8201
8202 /**
8203 * Produces a new {@code float} array containing the elements between the start and end indices.
8204 * <p>
8205 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8206 * </p>
8207 *
8208 * @param array the input array.
8209 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8210 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8211 * (>array.length) is demoted to array length.
8212 * @return a new array containing the elements between the start and end indices.
8213 * @since 2.1
8214 * @see Arrays#copyOfRange(float[], int, int)
8215 */
8216 public static float[] subarray(final float[] array, int startIndexInclusive, int endIndexExclusive) {
8217 if (array == null) {
8218 return null;
8219 }
8220 startIndexInclusive = max0(startIndexInclusive);
8221 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8222 final int newSize = endIndexExclusive - startIndexInclusive;
8223 if (newSize <= 0) {
8224 return EMPTY_FLOAT_ARRAY;
8225 }
8226 return arraycopy(array, startIndexInclusive, 0, newSize, float[]::new);
8227 }
8228
8229 /**
8230 * Produces a new {@code int} array containing the elements between the start and end indices.
8231 * <p>
8232 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8233 * </p>
8234 *
8235 * @param array the input array.
8236 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8237 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8238 * (>array.length) is demoted to array length.
8239 * @return a new array containing the elements between the start and end indices.
8240 * @since 2.1
8241 * @see Arrays#copyOfRange(int[], int, int)
8242 */
8243 public static int[] subarray(final int[] array, int startIndexInclusive, int endIndexExclusive) {
8244 if (array == null) {
8245 return null;
8246 }
8247 startIndexInclusive = max0(startIndexInclusive);
8248 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8249 final int newSize = endIndexExclusive - startIndexInclusive;
8250 if (newSize <= 0) {
8251 return EMPTY_INT_ARRAY;
8252 }
8253 return arraycopy(array, startIndexInclusive, 0, newSize, int[]::new);
8254 }
8255
8256 /**
8257 * Produces a new {@code long} array containing the elements between the start and end indices.
8258 * <p>
8259 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8260 * </p>
8261 *
8262 * @param array the input array.
8263 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8264 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8265 * (>array.length) is demoted to array length.
8266 * @return a new array containing the elements between the start and end indices.
8267 * @since 2.1
8268 * @see Arrays#copyOfRange(long[], int, int)
8269 */
8270 public static long[] subarray(final long[] array, int startIndexInclusive, int endIndexExclusive) {
8271 if (array == null) {
8272 return null;
8273 }
8274 startIndexInclusive = max0(startIndexInclusive);
8275 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8276 final int newSize = endIndexExclusive - startIndexInclusive;
8277 if (newSize <= 0) {
8278 return EMPTY_LONG_ARRAY;
8279 }
8280 return arraycopy(array, startIndexInclusive, 0, newSize, long[]::new);
8281 }
8282
8283 /**
8284 * Produces a new {@code short} array containing the elements between the start and end indices.
8285 * <p>
8286 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8287 * </p>
8288 *
8289 * @param array the input array.
8290 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8291 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8292 * (>array.length) is demoted to array length.
8293 * @return a new array containing the elements between the start and end indices.
8294 * @since 2.1
8295 * @see Arrays#copyOfRange(short[], int, int)
8296 */
8297 public static short[] subarray(final short[] array, int startIndexInclusive, int endIndexExclusive) {
8298 if (array == null) {
8299 return null;
8300 }
8301 startIndexInclusive = max0(startIndexInclusive);
8302 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8303 final int newSize = endIndexExclusive - startIndexInclusive;
8304 if (newSize <= 0) {
8305 return EMPTY_SHORT_ARRAY;
8306 }
8307 return arraycopy(array, startIndexInclusive, 0, newSize, short[]::new);
8308 }
8309
8310 /**
8311 * Produces a new array containing the elements between the start and end indices.
8312 * <p>
8313 * The start index is inclusive, the end index exclusive. Null array input produces null output.
8314 * </p>
8315 * <p>
8316 * The component type of the subarray is always the same as that of the input array. Thus, if the input is an array of type {@link Date}, the following
8317 * usage is envisaged:
8318 * </p>
8319 *
8320 * <pre>
8321 *
8322 * Date[] someDates = (Date[]) ArrayUtils.subarray(allDates, 2, 5);
8323 * </pre>
8324 *
8325 * @param <T> the component type of the array.
8326 * @param array the input array.
8327 * @param startIndexInclusive the starting index. Undervalue (<0) is promoted to 0, overvalue (>array.length) results in an empty array.
8328 * @param endIndexExclusive elements up to endIndex-1 are present in the returned subarray. Undervalue (< startIndex) produces empty array, overvalue
8329 * (>array.length) is demoted to array length.
8330 * @return a new array containing the elements between the start and end indices.
8331 * @since 2.1
8332 * @see Arrays#copyOfRange(Object[], int, int)
8333 */
8334 public static <T> T[] subarray(final T[] array, int startIndexInclusive, int endIndexExclusive) {
8335 if (array == null) {
8336 return null;
8337 }
8338 startIndexInclusive = max0(startIndexInclusive);
8339 endIndexExclusive = max0(Math.min(endIndexExclusive, array.length));
8340 final int newSize = endIndexExclusive - startIndexInclusive;
8341 final Class<T> type = getComponentType(array);
8342 if (newSize <= 0) {
8343 return newInstance(type, 0);
8344 }
8345 return arraycopy(array, startIndexInclusive, 0, newSize, () -> newInstance(type, newSize));
8346 }
8347
8348 /**
8349 * Swaps two elements in the given boolean array.
8350 *
8351 * <p>There is no special handling for multi-dimensional arrays. This method
8352 * does nothing for a {@code null} or empty input array or for overflow indices.
8353 * Negative indices are promoted to 0(zero).</p>
8354 *
8355 * Examples:
8356 * <ul>
8357 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8358 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8359 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8360 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8361 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8362 * </ul>
8363 *
8364 * @param array the array to swap, may be {@code null}.
8365 * @param offset1 the index of the first element to swap.
8366 * @param offset2 the index of the second element to swap.
8367 * @since 3.5
8368 */
8369 public static void swap(final boolean[] array, final int offset1, final int offset2) {
8370 swap(array, offset1, offset2, 1);
8371 }
8372
8373 /**
8374 * Swaps a series of elements in the given boolean array.
8375 *
8376 * <p>This method does nothing for a {@code null} or empty input array or
8377 * for overflow indices. Negative indices are promoted to 0(zero). If any
8378 * of the sub-arrays to swap falls outside of the given array, then the
8379 * swap is stopped at the end of the array and as many as possible elements
8380 * are swapped.</p>
8381 *
8382 * Examples:
8383 * <ul>
8384 * <li>ArrayUtils.swap([true, false, true, false], 0, 2, 1) -> [true, false, true, false]</li>
8385 * <li>ArrayUtils.swap([true, false, true, false], 0, 0, 1) -> [true, false, true, false]</li>
8386 * <li>ArrayUtils.swap([true, false, true, false], 0, 2, 2) -> [true, false, true, false]</li>
8387 * <li>ArrayUtils.swap([true, false, true, false], -3, 2, 2) -> [true, false, true, false]</li>
8388 * <li>ArrayUtils.swap([true, false, true, false], 0, 3, 3) -> [false, false, true, true]</li>
8389 * </ul>
8390 *
8391 * @param array the array to swap, may be {@code null}.
8392 * @param offset1 the index of the first element in the series to swap.
8393 * @param offset2 the index of the second element in the series to swap.
8394 * @param len the number of elements to swap starting with the given indices.
8395 * @since 3.5
8396 */
8397 public static void swap(final boolean[] array, int offset1, int offset2, int len) {
8398 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8399 return;
8400 }
8401 offset1 = max0(offset1);
8402 offset2 = max0(offset2);
8403 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8404 for (int i = 0; i < len; i++, offset1++, offset2++) {
8405 final boolean aux = array[offset1];
8406 array[offset1] = array[offset2];
8407 array[offset2] = aux;
8408 }
8409 }
8410
8411 /**
8412 * Swaps two elements in the given byte array.
8413 *
8414 * <p>There is no special handling for multi-dimensional arrays. This method
8415 * does nothing for a {@code null} or empty input array or for overflow indices.
8416 * Negative indices are promoted to 0(zero).</p>
8417 *
8418 * Examples:
8419 * <ul>
8420 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8421 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8422 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8423 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8424 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8425 * </ul>
8426 *
8427 * @param array the array to swap, may be {@code null}.
8428 * @param offset1 the index of the first element to swap.
8429 * @param offset2 the index of the second element to swap.
8430 * @since 3.5
8431 */
8432 public static void swap(final byte[] array, final int offset1, final int offset2) {
8433 swap(array, offset1, offset2, 1);
8434 }
8435
8436 /**
8437 * Swaps a series of elements in the given byte array.
8438 *
8439 * <p>This method does nothing for a {@code null} or empty input array or
8440 * for overflow indices. Negative indices are promoted to 0(zero). If any
8441 * of the sub-arrays to swap falls outside of the given array, then the
8442 * swap is stopped at the end of the array and as many as possible elements
8443 * are swapped.</p>
8444 *
8445 * Examples:
8446 * <ul>
8447 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8448 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8449 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8450 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8451 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8452 * </ul>
8453 *
8454 * @param array the array to swap, may be {@code null}.
8455 * @param offset1 the index of the first element in the series to swap.
8456 * @param offset2 the index of the second element in the series to swap.
8457 * @param len the number of elements to swap starting with the given indices.
8458 * @since 3.5
8459 */
8460 public static void swap(final byte[] array, int offset1, int offset2, int len) {
8461 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8462 return;
8463 }
8464 offset1 = max0(offset1);
8465 offset2 = max0(offset2);
8466 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8467 for (int i = 0; i < len; i++, offset1++, offset2++) {
8468 final byte aux = array[offset1];
8469 array[offset1] = array[offset2];
8470 array[offset2] = aux;
8471 }
8472 }
8473
8474 /**
8475 * Swaps two elements in the given char array.
8476 *
8477 * <p>There is no special handling for multi-dimensional arrays. This method
8478 * does nothing for a {@code null} or empty input array or for overflow indices.
8479 * Negative indices are promoted to 0(zero).</p>
8480 *
8481 * Examples:
8482 * <ul>
8483 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8484 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8485 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8486 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8487 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8488 * </ul>
8489 *
8490 * @param array the array to swap, may be {@code null}.
8491 * @param offset1 the index of the first element to swap.
8492 * @param offset2 the index of the second element to swap.
8493 * @since 3.5
8494 */
8495 public static void swap(final char[] array, final int offset1, final int offset2) {
8496 swap(array, offset1, offset2, 1);
8497 }
8498
8499 /**
8500 * Swaps a series of elements in the given char array.
8501 *
8502 * <p>This method does nothing for a {@code null} or empty input array or
8503 * for overflow indices. Negative indices are promoted to 0(zero). If any
8504 * of the sub-arrays to swap falls outside of the given array, then the
8505 * swap is stopped at the end of the array and as many as possible elements
8506 * are swapped.</p>
8507 *
8508 * Examples:
8509 * <ul>
8510 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8511 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8512 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8513 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8514 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8515 * </ul>
8516 *
8517 * @param array the array to swap, may be {@code null}.
8518 * @param offset1 the index of the first element in the series to swap.
8519 * @param offset2 the index of the second element in the series to swap.
8520 * @param len the number of elements to swap starting with the given indices.
8521 * @since 3.5
8522 */
8523 public static void swap(final char[] array, int offset1, int offset2, int len) {
8524 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8525 return;
8526 }
8527 offset1 = max0(offset1);
8528 offset2 = max0(offset2);
8529 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8530 for (int i = 0; i < len; i++, offset1++, offset2++) {
8531 final char aux = array[offset1];
8532 array[offset1] = array[offset2];
8533 array[offset2] = aux;
8534 }
8535 }
8536
8537 /**
8538 * Swaps two elements in the given double array.
8539 *
8540 * <p>There is no special handling for multi-dimensional arrays. This method
8541 * does nothing for a {@code null} or empty input array or for overflow indices.
8542 * Negative indices are promoted to 0(zero).</p>
8543 *
8544 * Examples:
8545 * <ul>
8546 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8547 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8548 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8549 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8550 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8551 * </ul>
8552 *
8553 * @param array the array to swap, may be {@code null}.
8554 * @param offset1 the index of the first element to swap.
8555 * @param offset2 the index of the second element to swap.
8556 * @since 3.5
8557 */
8558 public static void swap(final double[] array, final int offset1, final int offset2) {
8559 swap(array, offset1, offset2, 1);
8560 }
8561
8562 /**
8563 * Swaps a series of elements in the given double array.
8564 *
8565 * <p>This method does nothing for a {@code null} or empty input array or
8566 * for overflow indices. Negative indices are promoted to 0(zero). If any
8567 * of the sub-arrays to swap falls outside of the given array, then the
8568 * swap is stopped at the end of the array and as many as possible elements
8569 * are swapped.</p>
8570 *
8571 * Examples:
8572 * <ul>
8573 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8574 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8575 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8576 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8577 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8578 * </ul>
8579 *
8580 * @param array the array to swap, may be {@code null}.
8581 * @param offset1 the index of the first element in the series to swap.
8582 * @param offset2 the index of the second element in the series to swap.
8583 * @param len the number of elements to swap starting with the given indices.
8584 * @since 3.5
8585 */
8586 public static void swap(final double[] array, int offset1, int offset2, int len) {
8587 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8588 return;
8589 }
8590 offset1 = max0(offset1);
8591 offset2 = max0(offset2);
8592 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8593 for (int i = 0; i < len; i++, offset1++, offset2++) {
8594 final double aux = array[offset1];
8595 array[offset1] = array[offset2];
8596 array[offset2] = aux;
8597 }
8598 }
8599
8600 /**
8601 * Swaps two elements in the given float array.
8602 *
8603 * <p>There is no special handling for multi-dimensional arrays. This method
8604 * does nothing for a {@code null} or empty input array or for overflow indices.
8605 * Negative indices are promoted to 0(zero).</p>
8606 *
8607 * Examples:
8608 * <ul>
8609 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8610 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8611 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8612 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8613 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8614 * </ul>
8615 *
8616 * @param array the array to swap, may be {@code null}.
8617 * @param offset1 the index of the first element to swap.
8618 * @param offset2 the index of the second element to swap.
8619 * @since 3.5
8620 */
8621 public static void swap(final float[] array, final int offset1, final int offset2) {
8622 swap(array, offset1, offset2, 1);
8623 }
8624
8625 /**
8626 * Swaps a series of elements in the given float array.
8627 *
8628 * <p>This method does nothing for a {@code null} or empty input array or
8629 * for overflow indices. Negative indices are promoted to 0(zero). If any
8630 * of the sub-arrays to swap falls outside of the given array, then the
8631 * swap is stopped at the end of the array and as many as possible elements
8632 * are swapped.</p>
8633 *
8634 * Examples:
8635 * <ul>
8636 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8637 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8638 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8639 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8640 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8641 * </ul>
8642 *
8643 * @param array the array to swap, may be {@code null}.
8644 * @param offset1 the index of the first element in the series to swap.
8645 * @param offset2 the index of the second element in the series to swap.
8646 * @param len the number of elements to swap starting with the given indices.
8647 * @since 3.5
8648 */
8649 public static void swap(final float[] array, int offset1, int offset2, int len) {
8650 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8651 return;
8652 }
8653 offset1 = max0(offset1);
8654 offset2 = max0(offset2);
8655 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8656 for (int i = 0; i < len; i++, offset1++, offset2++) {
8657 final float aux = array[offset1];
8658 array[offset1] = array[offset2];
8659 array[offset2] = aux;
8660 }
8661
8662 }
8663
8664 /**
8665 * Swaps two elements in the given int array.
8666 *
8667 * <p>There is no special handling for multi-dimensional arrays. This method
8668 * does nothing for a {@code null} or empty input array or for overflow indices.
8669 * Negative indices are promoted to 0(zero).</p>
8670 *
8671 * Examples:
8672 * <ul>
8673 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8674 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8675 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8676 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8677 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8678 * </ul>
8679 *
8680 * @param array the array to swap, may be {@code null}.
8681 * @param offset1 the index of the first element to swap.
8682 * @param offset2 the index of the second element to swap.
8683 * @since 3.5
8684 */
8685 public static void swap(final int[] array, final int offset1, final int offset2) {
8686 swap(array, offset1, offset2, 1);
8687 }
8688
8689 /**
8690 * Swaps a series of elements in the given int array.
8691 *
8692 * <p>This method does nothing for a {@code null} or empty input array or
8693 * for overflow indices. Negative indices are promoted to 0(zero). If any
8694 * of the sub-arrays to swap falls outside of the given array, then the
8695 * swap is stopped at the end of the array and as many as possible elements
8696 * are swapped.</p>
8697 *
8698 * Examples:
8699 * <ul>
8700 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8701 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8702 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8703 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8704 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8705 * </ul>
8706 *
8707 * @param array the array to swap, may be {@code null}.
8708 * @param offset1 the index of the first element in the series to swap.
8709 * @param offset2 the index of the second element in the series to swap.
8710 * @param len the number of elements to swap starting with the given indices.
8711 * @since 3.5
8712 */
8713 public static void swap(final int[] array, int offset1, int offset2, int len) {
8714 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8715 return;
8716 }
8717 offset1 = max0(offset1);
8718 offset2 = max0(offset2);
8719 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8720 for (int i = 0; i < len; i++, offset1++, offset2++) {
8721 final int aux = array[offset1];
8722 array[offset1] = array[offset2];
8723 array[offset2] = aux;
8724 }
8725 }
8726
8727 /**
8728 * Swaps two elements in the given long array.
8729 *
8730 * <p>There is no special handling for multi-dimensional arrays. This method
8731 * does nothing for a {@code null} or empty input array or for overflow indices.
8732 * Negative indices are promoted to 0(zero).</p>
8733 *
8734 * Examples:
8735 * <ul>
8736 * <li>ArrayUtils.swap([true, false, true], 0, 2) -> [true, false, true]</li>
8737 * <li>ArrayUtils.swap([true, false, true], 0, 0) -> [true, false, true]</li>
8738 * <li>ArrayUtils.swap([true, false, true], 1, 0) -> [false, true, true]</li>
8739 * <li>ArrayUtils.swap([true, false, true], 0, 5) -> [true, false, true]</li>
8740 * <li>ArrayUtils.swap([true, false, true], -1, 1) -> [false, true, true]</li>
8741 * </ul>
8742 *
8743 * @param array the array to swap, may be {@code null}.
8744 * @param offset1 the index of the first element to swap.
8745 * @param offset2 the index of the second element to swap.
8746 * @since 3.5
8747 */
8748 public static void swap(final long[] array, final int offset1, final int offset2) {
8749 swap(array, offset1, offset2, 1);
8750 }
8751
8752 /**
8753 * Swaps a series of elements in the given long array.
8754 *
8755 * <p>This method does nothing for a {@code null} or empty input array or
8756 * for overflow indices. Negative indices are promoted to 0(zero). If any
8757 * of the sub-arrays to swap falls outside of the given array, then the
8758 * swap is stopped at the end of the array and as many as possible elements
8759 * are swapped.</p>
8760 *
8761 * Examples:
8762 * <ul>
8763 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8764 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8765 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8766 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8767 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8768 * </ul>
8769 *
8770 * @param array the array to swap, may be {@code null}.
8771 * @param offset1 the index of the first element in the series to swap.
8772 * @param offset2 the index of the second element in the series to swap.
8773 * @param len the number of elements to swap starting with the given indices.
8774 * @since 3.5
8775 */
8776 public static void swap(final long[] array, int offset1, int offset2, int len) {
8777 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8778 return;
8779 }
8780 offset1 = max0(offset1);
8781 offset2 = max0(offset2);
8782 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8783 for (int i = 0; i < len; i++, offset1++, offset2++) {
8784 final long aux = array[offset1];
8785 array[offset1] = array[offset2];
8786 array[offset2] = aux;
8787 }
8788 }
8789
8790 /**
8791 * Swaps two elements in the given array.
8792 *
8793 * <p>There is no special handling for multi-dimensional arrays. This method
8794 * does nothing for a {@code null} or empty input array or for overflow indices.
8795 * Negative indices are promoted to 0(zero).</p>
8796 *
8797 * Examples:
8798 * <ul>
8799 * <li>ArrayUtils.swap(["1", "2", "3"], 0, 2) -> ["3", "2", "1"]</li>
8800 * <li>ArrayUtils.swap(["1", "2", "3"], 0, 0) -> ["1", "2", "3"]</li>
8801 * <li>ArrayUtils.swap(["1", "2", "3"], 1, 0) -> ["2", "1", "3"]</li>
8802 * <li>ArrayUtils.swap(["1", "2", "3"], 0, 5) -> ["1", "2", "3"]</li>
8803 * <li>ArrayUtils.swap(["1", "2", "3"], -1, 1) -> ["2", "1", "3"]</li>
8804 * </ul>
8805 *
8806 * @param array the array to swap, may be {@code null}.
8807 * @param offset1 the index of the first element to swap.
8808 * @param offset2 the index of the second element to swap.
8809 * @since 3.5
8810 */
8811 public static void swap(final Object[] array, final int offset1, final int offset2) {
8812 swap(array, offset1, offset2, 1);
8813 }
8814
8815 /**
8816 * Swaps a series of elements in the given array.
8817 *
8818 * <p>This method does nothing for a {@code null} or empty input array or
8819 * for overflow indices. Negative indices are promoted to 0(zero). If any
8820 * of the sub-arrays to swap falls outside of the given array, then the
8821 * swap is stopped at the end of the array and as many as possible elements
8822 * are swapped.</p>
8823 *
8824 * Examples:
8825 * <ul>
8826 * <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 2, 1) -> ["3", "2", "1", "4"]</li>
8827 * <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 0, 1) -> ["1", "2", "3", "4"]</li>
8828 * <li>ArrayUtils.swap(["1", "2", "3", "4"], 2, 0, 2) -> ["3", "4", "1", "2"]</li>
8829 * <li>ArrayUtils.swap(["1", "2", "3", "4"], -3, 2, 2) -> ["3", "4", "1", "2"]</li>
8830 * <li>ArrayUtils.swap(["1", "2", "3", "4"], 0, 3, 3) -> ["4", "2", "3", "1"]</li>
8831 * </ul>
8832 *
8833 * @param array the array to swap, may be {@code null}.
8834 * @param offset1 the index of the first element in the series to swap.
8835 * @param offset2 the index of the second element in the series to swap.
8836 * @param len the number of elements to swap starting with the given indices.
8837 * @since 3.5
8838 */
8839 public static void swap(final Object[] array, int offset1, int offset2, int len) {
8840 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8841 return;
8842 }
8843 offset1 = max0(offset1);
8844 offset2 = max0(offset2);
8845 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8846 for (int i = 0; i < len; i++, offset1++, offset2++) {
8847 final Object aux = array[offset1];
8848 array[offset1] = array[offset2];
8849 array[offset2] = aux;
8850 }
8851 }
8852
8853 /**
8854 * Swaps two elements in the given short array.
8855 *
8856 * <p>There is no special handling for multi-dimensional arrays. This method
8857 * does nothing for a {@code null} or empty input array or for overflow indices.
8858 * Negative indices are promoted to 0(zero).</p>
8859 *
8860 * Examples:
8861 * <ul>
8862 * <li>ArrayUtils.swap([1, 2, 3], 0, 2) -> [3, 2, 1]</li>
8863 * <li>ArrayUtils.swap([1, 2, 3], 0, 0) -> [1, 2, 3]</li>
8864 * <li>ArrayUtils.swap([1, 2, 3], 1, 0) -> [2, 1, 3]</li>
8865 * <li>ArrayUtils.swap([1, 2, 3], 0, 5) -> [1, 2, 3]</li>
8866 * <li>ArrayUtils.swap([1, 2, 3], -1, 1) -> [2, 1, 3]</li>
8867 * </ul>
8868 *
8869 * @param array the array to swap, may be {@code null}.
8870 * @param offset1 the index of the first element to swap.
8871 * @param offset2 the index of the second element to swap.
8872 * @since 3.5
8873 */
8874 public static void swap(final short[] array, final int offset1, final int offset2) {
8875 swap(array, offset1, offset2, 1);
8876 }
8877
8878 /**
8879 * Swaps a series of elements in the given short array.
8880 *
8881 * <p>This method does nothing for a {@code null} or empty input array or
8882 * for overflow indices. Negative indices are promoted to 0(zero). If any
8883 * of the sub-arrays to swap falls outside of the given array, then the
8884 * swap is stopped at the end of the array and as many as possible elements
8885 * are swapped.</p>
8886 *
8887 * Examples:
8888 * <ul>
8889 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 2, 1) -> [3, 2, 1, 4]</li>
8890 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 0, 1) -> [1, 2, 3, 4]</li>
8891 * <li>ArrayUtils.swap([1, 2, 3, 4], 2, 0, 2) -> [3, 4, 1, 2]</li>
8892 * <li>ArrayUtils.swap([1, 2, 3, 4], -3, 2, 2) -> [3, 4, 1, 2]</li>
8893 * <li>ArrayUtils.swap([1, 2, 3, 4], 0, 3, 3) -> [4, 2, 3, 1]</li>
8894 * </ul>
8895 *
8896 * @param array the array to swap, may be {@code null}.
8897 * @param offset1 the index of the first element in the series to swap.
8898 * @param offset2 the index of the second element in the series to swap.
8899 * @param len the number of elements to swap starting with the given indices.
8900 * @since 3.5
8901 */
8902 public static void swap(final short[] array, int offset1, int offset2, int len) {
8903 if (isEmpty(array) || offset1 >= array.length || offset2 >= array.length) {
8904 return;
8905 }
8906 offset1 = max0(offset1);
8907 offset2 = max0(offset2);
8908 if (offset1 == offset2) {
8909 return;
8910 }
8911 len = Math.min(Math.min(len, array.length - offset1), array.length - offset2);
8912 for (int i = 0; i < len; i++, offset1++, offset2++) {
8913 final short aux = array[offset1];
8914 array[offset1] = array[offset2];
8915 array[offset2] = aux;
8916 }
8917 }
8918
8919 /**
8920 * Create a type-safe generic array.
8921 * <p>
8922 * The Java language does not allow an array to be created from a generic type:
8923 * </p>
8924 * <pre>
8925 public static <T> T[] createAnArray(int size) {
8926 return new T[size]; // compiler error here
8927 }
8928 public static <T> T[] createAnArray(int size) {
8929 return (T[]) new Object[size]; // ClassCastException at runtime
8930 }
8931 * </pre>
8932 * <p>
8933 * Therefore new arrays of generic types can be created with this method.
8934 * For example, an array of Strings can be created:
8935 * </p>
8936 * <pre>{@code
8937 * String[] array = ArrayUtils.toArray("1", "2");
8938 * String[] emptyArray = ArrayUtils.<String>toArray();
8939 * }</pre>
8940 * <p>
8941 * The method is typically used in scenarios, where the caller itself uses generic types
8942 * that have to be combined into an array.
8943 * </p>
8944 * <p>
8945 * Note, this method makes only sense to provide arguments of the same type so that the
8946 * compiler can deduce the type of the array itself. While it is possible to select the
8947 * type explicitly like in
8948 * {@code Number[] array = ArrayUtils.<Number>toArray(Integer.valueOf(42), Double.valueOf(Math.PI))},
8949 * there is no real advantage when compared to
8950 * {@code new Number[] {Integer.valueOf(42), Double.valueOf(Math.PI)}}.
8951 * </p>
8952 *
8953 * @param <T> the array's element type.
8954 * @param items the varargs array items, null allowed.
8955 * @return the array, not null unless a null array is passed in.
8956 * @since 3.0
8957 */
8958 public static <T> T[] toArray(@SuppressWarnings("unchecked") final T... items) {
8959 return items;
8960 }
8961
8962 /**
8963 * Converts the given array into a {@link java.util.Map}. Each element of the array must be either a {@link java.util.Map.Entry} or an Array, containing at
8964 * least two elements, where the first element is used as key and the second as value.
8965 * <p>
8966 * This method can be used to initialize:
8967 * </p>
8968 *
8969 * <pre>
8970 *
8971 * // Create a Map mapping colors.
8972 * Map colorMap = ArrayUtils.toMap(new String[][] { { "RED", "#FF0000" }, { "GREEN", "#00FF00" }, { "BLUE", "#0000FF" } });
8973 * </pre>
8974 * <p>
8975 * This method returns {@code null} for a {@code null} input array.
8976 * </p>
8977 *
8978 * @param array an array whose elements are either a {@link java.util.Map.Entry} or an Array containing at least two elements, may be {@code null}.
8979 * @return a {@link Map} that was created from the array.
8980 * @throws IllegalArgumentException if one element of this Array is itself an Array containing less than two elements.
8981 * @throws IllegalArgumentException if the array contains elements other than {@link java.util.Map.Entry} and an Array.
8982 */
8983 public static Map<Object, Object> toMap(final Object[] array) {
8984 if (array == null) {
8985 return null;
8986 }
8987 final Map<Object, Object> map = new HashMap<>((int) (array.length * 1.5));
8988 for (int i = 0; i < array.length; i++) {
8989 final Object object = array[i];
8990 if (object instanceof Map.Entry<?, ?>) {
8991 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
8992 map.put(entry.getKey(), entry.getValue());
8993 } else if (object instanceof Object[]) {
8994 final Object[] entry = (Object[]) object;
8995 if (entry.length < 2) {
8996 throw new IllegalArgumentException("Array element " + i + ", '"
8997 + object
8998 + "', has a length less than 2");
8999 }
9000 map.put(entry[0], entry[1]);
9001 } else {
9002 throw new IllegalArgumentException("Array element " + i + ", '"
9003 + object
9004 + "', is neither of type Map.Entry nor an Array");
9005 }
9006 }
9007 return map;
9008 }
9009
9010 /**
9011 * Converts an array of primitive booleans to objects.
9012 *
9013 * <p>This method returns {@code null} for a {@code null} input array.</p>
9014 *
9015 * @param array a {@code boolean} array.
9016 * @return a {@link Boolean} array, {@code null} if null array input.
9017 */
9018 public static Boolean[] toObject(final boolean[] array) {
9019 if (array == null) {
9020 return null;
9021 }
9022 if (array.length == 0) {
9023 return EMPTY_BOOLEAN_OBJECT_ARRAY;
9024 }
9025 return setAll(new Boolean[array.length], i -> array[i] ? Boolean.TRUE : Boolean.FALSE);
9026 }
9027
9028 /**
9029 * Converts an array of primitive bytes to objects.
9030 *
9031 * <p>This method returns {@code null} for a {@code null} input array.</p>
9032 *
9033 * @param array a {@code byte} array.
9034 * @return a {@link Byte} array, {@code null} if null array input.
9035 */
9036 public static Byte[] toObject(final byte[] array) {
9037 if (array == null) {
9038 return null;
9039 }
9040 if (array.length == 0) {
9041 return EMPTY_BYTE_OBJECT_ARRAY;
9042 }
9043 return setAll(new Byte[array.length], i -> Byte.valueOf(array[i]));
9044 }
9045
9046 /**
9047 * Converts an array of primitive chars to objects.
9048 *
9049 * <p>This method returns {@code null} for a {@code null} input array.</p>
9050 *
9051 * @param array a {@code char} array.
9052 * @return a {@link Character} array, {@code null} if null array input.
9053 */
9054 public static Character[] toObject(final char[] array) {
9055 if (array == null) {
9056 return null;
9057 }
9058 if (array.length == 0) {
9059 return EMPTY_CHARACTER_OBJECT_ARRAY;
9060 }
9061 return setAll(new Character[array.length], i -> Character.valueOf(array[i]));
9062 }
9063
9064 /**
9065 * Converts an array of primitive doubles to objects.
9066 *
9067 * <p>This method returns {@code null} for a {@code null} input array.</p>
9068 *
9069 * @param array a {@code double} array.
9070 * @return a {@link Double} array, {@code null} if null array input.
9071 */
9072 public static Double[] toObject(final double[] array) {
9073 if (array == null) {
9074 return null;
9075 }
9076 if (array.length == 0) {
9077 return EMPTY_DOUBLE_OBJECT_ARRAY;
9078 }
9079 return setAll(new Double[array.length], i -> Double.valueOf(array[i]));
9080 }
9081
9082 /**
9083 * Converts an array of primitive floats to objects.
9084 *
9085 * <p>This method returns {@code null} for a {@code null} input array.</p>
9086 *
9087 * @param array a {@code float} array.
9088 * @return a {@link Float} array, {@code null} if null array input.
9089 */
9090 public static Float[] toObject(final float[] array) {
9091 if (array == null) {
9092 return null;
9093 }
9094 if (array.length == 0) {
9095 return EMPTY_FLOAT_OBJECT_ARRAY;
9096 }
9097 return setAll(new Float[array.length], i -> Float.valueOf(array[i]));
9098 }
9099
9100 /**
9101 * Converts an array of primitive ints to objects.
9102 *
9103 * <p>This method returns {@code null} for a {@code null} input array.</p>
9104 *
9105 * @param array an {@code int} array.
9106 * @return an {@link Integer} array, {@code null} if null array input.
9107 */
9108 public static Integer[] toObject(final int[] array) {
9109 if (array == null) {
9110 return null;
9111 }
9112 if (array.length == 0) {
9113 return EMPTY_INTEGER_OBJECT_ARRAY;
9114 }
9115 return setAll(new Integer[array.length], i -> Integer.valueOf(array[i]));
9116 }
9117
9118 /**
9119 * Converts an array of primitive longs to objects.
9120 *
9121 * <p>This method returns {@code null} for a {@code null} input array.</p>
9122 *
9123 * @param array a {@code long} array.
9124 * @return a {@link Long} array, {@code null} if null array input.
9125 */
9126 public static Long[] toObject(final long[] array) {
9127 if (array == null) {
9128 return null;
9129 }
9130 if (array.length == 0) {
9131 return EMPTY_LONG_OBJECT_ARRAY;
9132 }
9133 return setAll(new Long[array.length], i -> Long.valueOf(array[i]));
9134 }
9135
9136 /**
9137 * Converts an array of primitive shorts to objects.
9138 *
9139 * <p>This method returns {@code null} for a {@code null} input array.</p>
9140 *
9141 * @param array a {@code short} array.
9142 * @return a {@link Short} array, {@code null} if null array input.
9143 */
9144 public static Short[] toObject(final short[] array) {
9145 if (array == null) {
9146 return null;
9147 }
9148 if (array.length == 0) {
9149 return EMPTY_SHORT_OBJECT_ARRAY;
9150 }
9151 return setAll(new Short[array.length], i -> Short.valueOf(array[i]));
9152 }
9153
9154 /**
9155 * Converts an array of object Booleans to primitives.
9156 * <p>
9157 * This method returns {@code null} for a {@code null} input array.
9158 * </p>
9159 * <p>
9160 * Null array elements map to false, like {@code Boolean.parseBoolean(null)} and its callers return false.
9161 * </p>
9162 *
9163 * @param array a {@link Boolean} array, may be {@code null}.
9164 * @return a {@code boolean} array, {@code null} if null array input.
9165 */
9166 public static boolean[] toPrimitive(final Boolean[] array) {
9167 return toPrimitive(array, false);
9168 }
9169
9170 /**
9171 * Converts an array of object Booleans to primitives handling {@code null}.
9172 * <p>
9173 * This method returns {@code null} for a {@code null} input array.
9174 * </p>
9175 *
9176 * @param array a {@link Boolean} array, may be {@code null}.
9177 * @param valueForNull the value to insert if {@code null} found.
9178 * @return a {@code boolean} array, {@code null} if null array input.
9179 */
9180 public static boolean[] toPrimitive(final Boolean[] array, final boolean valueForNull) {
9181 if (array == null) {
9182 return null;
9183 }
9184 if (array.length == 0) {
9185 return EMPTY_BOOLEAN_ARRAY;
9186 }
9187 final boolean[] result = new boolean[array.length];
9188 for (int i = 0; i < array.length; i++) {
9189 final Boolean b = array[i];
9190 result[i] = b == null ? valueForNull : b.booleanValue();
9191 }
9192 return result;
9193 }
9194
9195 /**
9196 * Converts an array of object Bytes to primitives.
9197 * <p>
9198 * This method returns {@code null} for a {@code null} input array.
9199 * </p>
9200 *
9201 * @param array a {@link Byte} array, may be {@code null}.
9202 * @return a {@code byte} array, {@code null} if null array input.
9203 * @throws NullPointerException if an array element is {@code null}.
9204 */
9205 public static byte[] toPrimitive(final Byte[] array) {
9206 if (array == null) {
9207 return null;
9208 }
9209 if (array.length == 0) {
9210 return EMPTY_BYTE_ARRAY;
9211 }
9212 final byte[] result = new byte[array.length];
9213 for (int i = 0; i < array.length; i++) {
9214 result[i] = array[i].byteValue();
9215 }
9216 return result;
9217 }
9218
9219 /**
9220 * Converts an array of object Bytes to primitives handling {@code null}.
9221 * <p>
9222 * This method returns {@code null} for a {@code null} input array.
9223 * </p>
9224 *
9225 * @param array a {@link Byte} array, may be {@code null}.
9226 * @param valueForNull the value to insert if {@code null} found.
9227 * @return a {@code byte} array, {@code null} if null array input.
9228 */
9229 public static byte[] toPrimitive(final Byte[] array, final byte valueForNull) {
9230 if (array == null) {
9231 return null;
9232 }
9233 if (array.length == 0) {
9234 return EMPTY_BYTE_ARRAY;
9235 }
9236 final byte[] result = new byte[array.length];
9237 for (int i = 0; i < array.length; i++) {
9238 final Byte b = array[i];
9239 result[i] = b == null ? valueForNull : b.byteValue();
9240 }
9241 return result;
9242 }
9243
9244 /**
9245 * Converts an array of object Characters to primitives.
9246 * <p>
9247 * This method returns {@code null} for a {@code null} input array.
9248 * </p>
9249 *
9250 * @param array a {@link Character} array, may be {@code null}.
9251 * @return a {@code char} array, {@code null} if null array input.
9252 * @throws NullPointerException if an array element is {@code null}.
9253 */
9254 public static char[] toPrimitive(final Character[] array) {
9255 if (array == null) {
9256 return null;
9257 }
9258 if (array.length == 0) {
9259 return EMPTY_CHAR_ARRAY;
9260 }
9261 final char[] result = new char[array.length];
9262 for (int i = 0; i < array.length; i++) {
9263 result[i] = array[i].charValue();
9264 }
9265 return result;
9266 }
9267
9268 /**
9269 * Converts an array of object Character to primitives handling {@code null}.
9270 * <p>
9271 * This method returns {@code null} for a {@code null} input array.
9272 * </p>
9273 *
9274 * @param array a {@link Character} array, may be {@code null}.
9275 * @param valueForNull the value to insert if {@code null} found.
9276 * @return a {@code char} array, {@code null} if null array input.
9277 */
9278 public static char[] toPrimitive(final Character[] array, final char valueForNull) {
9279 if (array == null) {
9280 return null;
9281 }
9282 if (array.length == 0) {
9283 return EMPTY_CHAR_ARRAY;
9284 }
9285 final char[] result = new char[array.length];
9286 for (int i = 0; i < array.length; i++) {
9287 final Character b = array[i];
9288 result[i] = b == null ? valueForNull : b.charValue();
9289 }
9290 return result;
9291 }
9292
9293 /**
9294 * Converts an array of object Doubles to primitives.
9295 * <p>
9296 * This method returns {@code null} for a {@code null} input array.
9297 * </p>
9298 *
9299 * @param array a {@link Double} array, may be {@code null}.
9300 * @return a {@code double} array, {@code null} if null array input.
9301 * @throws NullPointerException if an array element is {@code null}.
9302 */
9303 public static double[] toPrimitive(final Double[] array) {
9304 if (array == null) {
9305 return null;
9306 }
9307 if (array.length == 0) {
9308 return EMPTY_DOUBLE_ARRAY;
9309 }
9310 final double[] result = new double[array.length];
9311 for (int i = 0; i < array.length; i++) {
9312 result[i] = array[i].doubleValue();
9313 }
9314 return result;
9315 }
9316
9317 /**
9318 * Converts an array of object Doubles to primitives handling {@code null}.
9319 * <p>
9320 * This method returns {@code null} for a {@code null} input array.
9321 * </p>
9322 *
9323 * @param array a {@link Double} array, may be {@code null}.
9324 * @param valueForNull the value to insert if {@code null} found.
9325 * @return a {@code double} array, {@code null} if null array input.
9326 */
9327 public static double[] toPrimitive(final Double[] array, final double valueForNull) {
9328 if (array == null) {
9329 return null;
9330 }
9331 if (array.length == 0) {
9332 return EMPTY_DOUBLE_ARRAY;
9333 }
9334 final double[] result = new double[array.length];
9335 for (int i = 0; i < array.length; i++) {
9336 final Double b = array[i];
9337 result[i] = b == null ? valueForNull : b.doubleValue();
9338 }
9339 return result;
9340 }
9341
9342 /**
9343 * Converts an array of object Floats to primitives.
9344 * <p>
9345 * This method returns {@code null} for a {@code null} input array.
9346 * </p>
9347 *
9348 * @param array a {@link Float} array, may be {@code null}.
9349 * @return a {@code float} array, {@code null} if null array input.
9350 * @throws NullPointerException if an array element is {@code null}.
9351 */
9352 public static float[] toPrimitive(final Float[] array) {
9353 if (array == null) {
9354 return null;
9355 }
9356 if (array.length == 0) {
9357 return EMPTY_FLOAT_ARRAY;
9358 }
9359 final float[] result = new float[array.length];
9360 for (int i = 0; i < array.length; i++) {
9361 result[i] = array[i].floatValue();
9362 }
9363 return result;
9364 }
9365
9366 /**
9367 * Converts an array of object Floats to primitives handling {@code null}.
9368 * <p>
9369 * This method returns {@code null} for a {@code null} input array.
9370 * </p>
9371 *
9372 * @param array a {@link Float} array, may be {@code null}.
9373 * @param valueForNull the value to insert if {@code null} found.
9374 * @return a {@code float} array, {@code null} if null array input.
9375 */
9376 public static float[] toPrimitive(final Float[] array, final float valueForNull) {
9377 if (array == null) {
9378 return null;
9379 }
9380 if (array.length == 0) {
9381 return EMPTY_FLOAT_ARRAY;
9382 }
9383 final float[] result = new float[array.length];
9384 for (int i = 0; i < array.length; i++) {
9385 final Float b = array[i];
9386 result[i] = b == null ? valueForNull : b.floatValue();
9387 }
9388 return result;
9389 }
9390
9391 /**
9392 * Converts an array of object Integers to primitives.
9393 * <p>
9394 * This method returns {@code null} for a {@code null} input array.
9395 * </p>
9396 *
9397 * @param array a {@link Integer} array, may be {@code null}.
9398 * @return an {@code int} array, {@code null} if null array input.
9399 * @throws NullPointerException if an array element is {@code null}.
9400 */
9401 public static int[] toPrimitive(final Integer[] array) {
9402 if (array == null) {
9403 return null;
9404 }
9405 if (array.length == 0) {
9406 return EMPTY_INT_ARRAY;
9407 }
9408 final int[] result = new int[array.length];
9409 for (int i = 0; i < array.length; i++) {
9410 result[i] = array[i].intValue();
9411 }
9412 return result;
9413 }
9414
9415 /**
9416 * Converts an array of object Integer to primitives handling {@code null}.
9417 * <p>
9418 * This method returns {@code null} for a {@code null} input array.
9419 * </p>
9420 *
9421 * @param array a {@link Integer} array, may be {@code null}.
9422 * @param valueForNull the value to insert if {@code null} found.
9423 * @return an {@code int} array, {@code null} if null array input.
9424 */
9425 public static int[] toPrimitive(final Integer[] array, final int valueForNull) {
9426 if (array == null) {
9427 return null;
9428 }
9429 if (array.length == 0) {
9430 return EMPTY_INT_ARRAY;
9431 }
9432 final int[] result = new int[array.length];
9433 for (int i = 0; i < array.length; i++) {
9434 final Integer b = array[i];
9435 result[i] = b == null ? valueForNull : b.intValue();
9436 }
9437 return result;
9438 }
9439
9440 /**
9441 * Converts an array of object Longs to primitives.
9442 * <p>
9443 * This method returns {@code null} for a {@code null} input array.
9444 * </p>
9445 *
9446 * @param array a {@link Long} array, may be {@code null}.
9447 * @return a {@code long} array, {@code null} if null array input.
9448 * @throws NullPointerException if an array element is {@code null}.
9449 */
9450 public static long[] toPrimitive(final Long[] array) {
9451 if (array == null) {
9452 return null;
9453 }
9454 if (array.length == 0) {
9455 return EMPTY_LONG_ARRAY;
9456 }
9457 final long[] result = new long[array.length];
9458 for (int i = 0; i < array.length; i++) {
9459 result[i] = array[i].longValue();
9460 }
9461 return result;
9462 }
9463
9464 /**
9465 * Converts an array of object Long to primitives handling {@code null}.
9466 * <p>
9467 * This method returns {@code null} for a {@code null} input array.
9468 * </p>
9469 *
9470 * @param array a {@link Long} array, may be {@code null}.
9471 * @param valueForNull the value to insert if {@code null} found.
9472 * @return a {@code long} array, {@code null} if null array input.
9473 */
9474 public static long[] toPrimitive(final Long[] array, final long valueForNull) {
9475 if (array == null) {
9476 return null;
9477 }
9478 if (array.length == 0) {
9479 return EMPTY_LONG_ARRAY;
9480 }
9481 final long[] result = new long[array.length];
9482 for (int i = 0; i < array.length; i++) {
9483 final Long b = array[i];
9484 result[i] = b == null ? valueForNull : b.longValue();
9485 }
9486 return result;
9487 }
9488
9489 /**
9490 * Create an array of primitive type from an array of wrapper types.
9491 * <p>
9492 * This method returns {@code null} for a {@code null} input array.
9493 * </p>
9494 *
9495 * @param array an array of wrapper object.
9496 * @return an array of the corresponding primitive type, or the original array.
9497 * @since 3.5
9498 */
9499 public static Object toPrimitive(final Object array) {
9500 if (array == null) {
9501 return null;
9502 }
9503 final Class<?> ct = array.getClass().getComponentType();
9504 final Class<?> pt = ClassUtils.wrapperToPrimitive(ct);
9505 if (Boolean.TYPE.equals(pt)) {
9506 return toPrimitive((Boolean[]) array);
9507 }
9508 if (Character.TYPE.equals(pt)) {
9509 return toPrimitive((Character[]) array);
9510 }
9511 if (Byte.TYPE.equals(pt)) {
9512 return toPrimitive((Byte[]) array);
9513 }
9514 if (Integer.TYPE.equals(pt)) {
9515 return toPrimitive((Integer[]) array);
9516 }
9517 if (Long.TYPE.equals(pt)) {
9518 return toPrimitive((Long[]) array);
9519 }
9520 if (Short.TYPE.equals(pt)) {
9521 return toPrimitive((Short[]) array);
9522 }
9523 if (Double.TYPE.equals(pt)) {
9524 return toPrimitive((Double[]) array);
9525 }
9526 if (Float.TYPE.equals(pt)) {
9527 return toPrimitive((Float[]) array);
9528 }
9529 return array;
9530 }
9531
9532 /**
9533 * Converts an array of object Shorts to primitives.
9534 * <p>
9535 * This method returns {@code null} for a {@code null} input array.
9536 * </p>
9537 *
9538 * @param array a {@link Short} array, may be {@code null}.
9539 * @return a {@code byte} array, {@code null} if null array input.
9540 * @throws NullPointerException if an array element is {@code null}.
9541 */
9542 public static short[] toPrimitive(final Short[] array) {
9543 if (array == null) {
9544 return null;
9545 }
9546 if (array.length == 0) {
9547 return EMPTY_SHORT_ARRAY;
9548 }
9549 final short[] result = new short[array.length];
9550 for (int i = 0; i < array.length; i++) {
9551 result[i] = array[i].shortValue();
9552 }
9553 return result;
9554 }
9555
9556 /**
9557 * Converts an array of object Short to primitives handling {@code null}.
9558 * <p>
9559 * This method returns {@code null} for a {@code null} input array.
9560 * </p>
9561 *
9562 * @param array a {@link Short} array, may be {@code null}.
9563 * @param valueForNull the value to insert if {@code null} found.
9564 * @return a {@code byte} array, {@code null} if null array input.
9565 */
9566 public static short[] toPrimitive(final Short[] array, final short valueForNull) {
9567 if (array == null) {
9568 return null;
9569 }
9570 if (array.length == 0) {
9571 return EMPTY_SHORT_ARRAY;
9572 }
9573 final short[] result = new short[array.length];
9574 for (int i = 0; i < array.length; i++) {
9575 final Short b = array[i];
9576 result[i] = b == null ? valueForNull : b.shortValue();
9577 }
9578 return result;
9579 }
9580
9581 /**
9582 * Outputs an array as a String, treating {@code null} as an empty array.
9583 * <p>
9584 * Multi-dimensional arrays are handled correctly, including
9585 * multi-dimensional primitive arrays.
9586 * </p>
9587 * <p>
9588 * The format is that of Java source code, for example {@code {a,b}}.
9589 * </p>
9590 *
9591 * @param array the array to get a toString for, may be {@code null}.
9592 * @return a String representation of the array, '{}' if null array input.
9593 */
9594 public static String toString(final Object array) {
9595 return toString(array, "{}");
9596 }
9597
9598 /**
9599 * Outputs an array as a String handling {@code null}s.
9600 * <p>
9601 * Multi-dimensional arrays are handled correctly, including
9602 * multi-dimensional primitive arrays.
9603 * </p>
9604 * <p>
9605 * The format is that of Java source code, for example {@code {a,b}}.
9606 * </p>
9607 *
9608 * @param array the array to get a toString for, may be {@code null}.
9609 * @param stringIfNull the String to return if the array is {@code null}.
9610 * @return a String representation of the array.
9611 */
9612 public static String toString(final Object array, final String stringIfNull) {
9613 return array != null ? new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString() : stringIfNull;
9614 }
9615
9616 /**
9617 * Returns an array containing the string representation of each element in the argument array.
9618 * <p>
9619 * This method returns {@code null} for a {@code null} input array.
9620 * </p>
9621 *
9622 * @param array the {@code Object[]} to be processed, may be {@code null}.
9623 * @return {@code String[]} of the same size as the source with its element's string representation, {@code null} if null array input.
9624 * @since 3.6
9625 */
9626 public static String[] toStringArray(final Object[] array) {
9627 return toStringArray(array, "null");
9628 }
9629
9630 /**
9631 * Returns an array containing the string representation of each element in the argument array handling {@code null} elements.
9632 * <p>
9633 * This method returns {@code null} for a {@code null} input array.
9634 * </p>
9635 *
9636 * @param array the Object[] to be processed, may be {@code null}.
9637 * @param valueForNullElements the value to insert if {@code null} is found.
9638 * @return a {@link String} array, {@code null} if null array input.
9639 * @since 3.6
9640 */
9641 public static String[] toStringArray(final Object[] array, final String valueForNullElements) {
9642 if (null == array) {
9643 return null;
9644 }
9645 if (array.length == 0) {
9646 return EMPTY_STRING_ARRAY;
9647 }
9648 return map(array, String.class, e -> Objects.toString(e, valueForNullElements));
9649 }
9650
9651 /**
9652 * ArrayUtils instances should NOT be constructed in standard programming. Instead, the class should be used as {@code ArrayUtils.clone(new int[] {2})}.
9653 * <p>
9654 * This constructor is public to permit tools that require a JavaBean instance to operate.
9655 * </p>
9656 *
9657 * @deprecated TODO Make private in 4.0.
9658 */
9659 @Deprecated
9660 public ArrayUtils() {
9661 // empty
9662 }
9663 }