1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.lang3;
18
19 import java.lang.reflect.Array;
20 import java.util.Arrays;
21 import java.util.BitSet;
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import org.apache.commons.lang3.builder.EqualsBuilder;
26 import org.apache.commons.lang3.builder.HashCodeBuilder;
27 import org.apache.commons.lang3.builder.ToStringBuilder;
28 import org.apache.commons.lang3.builder.ToStringStyle;
29 import org.apache.commons.lang3.mutable.MutableInt;
30
31 /**
32 * <p>Operations on arrays, primitive arrays (like {@code int[]}) and
33 * primitive wrapper arrays (like {@code Integer[]}).</p>
34 *
35 * <p>This class tries to handle {@code null} input gracefully.
36 * An exception will not be thrown for a {@code null}
37 * array input. However, an Object array that contains a {@code null}
38 * element may throw an exception. Each method documents its behaviour.</p>
39 *
40 * <p>#ThreadSafe#</p>
41 * @since 2.0
42 * @version $Id: ArrayUtils.java 1436770 2013-01-22 07:09:45Z ggregory $
43 */
44 public class ArrayUtils {
45
46 /**
47 * An empty immutable {@code Object} array.
48 */
49 public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
50 /**
51 * An empty immutable {@code Class} array.
52 */
53 public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0];
54 /**
55 * An empty immutable {@code String} array.
56 */
57 public static final String[] EMPTY_STRING_ARRAY = new String[0];
58 /**
59 * An empty immutable {@code long} array.
60 */
61 public static final long[] EMPTY_LONG_ARRAY = new long[0];
62 /**
63 * An empty immutable {@code Long} array.
64 */
65 public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
66 /**
67 * An empty immutable {@code int} array.
68 */
69 public static final int[] EMPTY_INT_ARRAY = new int[0];
70 /**
71 * An empty immutable {@code Integer} array.
72 */
73 public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
74 /**
75 * An empty immutable {@code short} array.
76 */
77 public static final short[] EMPTY_SHORT_ARRAY = new short[0];
78 /**
79 * An empty immutable {@code Short} array.
80 */
81 public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
82 /**
83 * An empty immutable {@code byte} array.
84 */
85 public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
86 /**
87 * An empty immutable {@code Byte} array.
88 */
89 public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
90 /**
91 * An empty immutable {@code double} array.
92 */
93 public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
94 /**
95 * An empty immutable {@code Double} array.
96 */
97 public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
98 /**
99 * An empty immutable {@code float} array.
100 */
101 public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
102 /**
103 * An empty immutable {@code Float} array.
104 */
105 public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
106 /**
107 * An empty immutable {@code boolean} array.
108 */
109 public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
110 /**
111 * An empty immutable {@code Boolean} array.
112 */
113 public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
114 /**
115 * An empty immutable {@code char} array.
116 */
117 public static final char[] EMPTY_CHAR_ARRAY = new char[0];
118 /**
119 * An empty immutable {@code Character} array.
120 */
121 public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
122
123 /**
124 * The index value when an element is not found in a list or array: {@code -1}.
125 * This value is returned by methods in this class and can also be used in comparisons with values returned by
126 * various method from {@link java.util.List}.
127 */
128 public static final int INDEX_NOT_FOUND = -1;
129
130 /**
131 * <p>ArrayUtils instances should NOT be constructed in standard programming.
132 * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
133 *
134 * <p>This constructor is public to permit tools that require a JavaBean instance
135 * to operate.</p>
136 */
137 public ArrayUtils() {
138 super();
139 }
140
141
142 // NOTE: Cannot use {@code} to enclose text which includes {}, but <code></code> is OK
143
144
145 // Basic methods handling multi-dimensional arrays
146 //-----------------------------------------------------------------------
147 /**
148 * <p>Outputs an array as a String, treating {@code null} as an empty array.</p>
149 *
150 * <p>Multi-dimensional arrays are handled correctly, including
151 * multi-dimensional primitive arrays.</p>
152 *
153 * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
154 *
155 * @param array the array to get a toString for, may be {@code null}
156 * @return a String representation of the array, '{}' if null array input
157 */
158 public static String toString(final Object array) {
159 return toString(array, "{}");
160 }
161
162 /**
163 * <p>Outputs an array as a String handling {@code null}s.</p>
164 *
165 * <p>Multi-dimensional arrays are handled correctly, including
166 * multi-dimensional primitive arrays.</p>
167 *
168 * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
169 *
170 * @param array the array to get a toString for, may be {@code null}
171 * @param stringIfNull the String to return if the array is {@code null}
172 * @return a String representation of the array
173 */
174 public static String toString(final Object array, final String stringIfNull) {
175 if (array == null) {
176 return stringIfNull;
177 }
178 return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
179 }
180
181 /**
182 * <p>Get a hash code for an array handling multi-dimensional arrays correctly.</p>
183 *
184 * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
185 *
186 * @param array the array to get a hash code for, {@code null} returns zero
187 * @return a hash code for the array
188 */
189 public static int hashCode(final Object array) {
190 return new HashCodeBuilder().append(array).toHashCode();
191 }
192
193 /**
194 * <p>Compares two arrays, using equals(), handling multi-dimensional arrays
195 * correctly.</p>
196 *
197 * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
198 *
199 * @param array1 the left hand array to compare, may be {@code null}
200 * @param array2 the right hand array to compare, may be {@code null}
201 * @return {@code true} if the arrays are equal
202 */
203 public static boolean isEquals(final Object array1, final Object array2) {
204 return new EqualsBuilder().append(array1, array2).isEquals();
205 }
206
207 // To map
208 //-----------------------------------------------------------------------
209 /**
210 * <p>Converts the given array into a {@link java.util.Map}. Each element of the array
211 * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
212 * elements, where the first element is used as key and the second as
213 * value.</p>
214 *
215 * <p>This method can be used to initialize:</p>
216 * <pre>
217 * // Create a Map mapping colors.
218 * Map colorMap = MapUtils.toMap(new String[][] {{
219 * {"RED", "#FF0000"},
220 * {"GREEN", "#00FF00"},
221 * {"BLUE", "#0000FF"}});
222 * </pre>
223 *
224 * <p>This method returns {@code null} for a {@code null} input array.</p>
225 *
226 * @param array an array whose elements are either a {@link java.util.Map.Entry} or
227 * an Array containing at least two elements, may be {@code null}
228 * @return a {@code Map} that was created from the array
229 * @throws IllegalArgumentException if one element of this Array is
230 * itself an Array containing less then two elements
231 * @throws IllegalArgumentException if the array contains elements other
232 * than {@link java.util.Map.Entry} and an Array
233 */
234 public static Map<Object, Object> toMap(final Object[] array) {
235 if (array == null) {
236 return null;
237 }
238 final Map<Object, Object> map = new HashMap<Object, Object>((int) (array.length * 1.5));
239 for (int i = 0; i < array.length; i++) {
240 final Object object = array[i];
241 if (object instanceof Map.Entry<?, ?>) {
242 final Map.Entry<?,?> entry = (Map.Entry<?,?>) object;
243 map.put(entry.getKey(), entry.getValue());
244 } else if (object instanceof Object[]) {
245 final Object[] entry = (Object[]) object;
246 if (entry.length < 2) {
247 throw new IllegalArgumentException("Array element " + i + ", '"
248 + object
249 + "', has a length less than 2");
250 }
251 map.put(entry[0], entry[1]);
252 } else {
253 throw new IllegalArgumentException("Array element " + i + ", '"
254 + object
255 + "', is neither of type Map.Entry nor an Array");
256 }
257 }
258 return map;
259 }
260
261 // Generic array
262 //-----------------------------------------------------------------------
263 /**
264 * <p>Create a type-safe generic array.</p>
265 *
266 * <p>The Java language does not allow an array to be created from a generic type:</p>
267 *
268 * <pre>
269 public static <T> T[] createAnArray(int size) {
270 return new T[size]; // compiler error here
271 }
272 public static <T> T[] createAnArray(int size) {
273 return (T[])new Object[size]; // ClassCastException at runtime
274 }
275 * </pre>
276 *
277 * <p>Therefore new arrays of generic types can be created with this method.
278 * For example, an array of Strings can be created:</p>
279 *
280 * <pre>
281 String[] array = ArrayUtils.toArray("1", "2");
282 String[] emptyArray = ArrayUtils.<String>toArray();
283 * </pre>
284 *
285 * <p>The method is typically used in scenarios, where the caller itself uses generic types
286 * that have to be combined into an array.</p>
287 *
288 * <p>Note, this method makes only sense to provide arguments of the same type so that the
289 * compiler can deduce the type of the array itself. While it is possible to select the
290 * type explicitly like in
291 * <code>Number[] array = ArrayUtils.<Number>toArray(Integer.valueOf(42), Double.valueOf(Math.PI))</code>,
292 * there is no real advantage when compared to
293 * <code>new Number[] {Integer.valueOf(42), Double.valueOf(Math.PI)}</code>.</p>
294 *
295 * @param <T> the array's element type
296 * @param items the varargs array items, null allowed
297 * @return the array, not null unless a null array is passed in
298 * @since 3.0
299 */
300 public static <T> T[] toArray(final T... items) {
301 return items;
302 }
303
304 // Clone
305 //-----------------------------------------------------------------------
306 /**
307 * <p>Shallow clones an array returning a typecast result and handling
308 * {@code null}.</p>
309 *
310 * <p>The objects in the array are not cloned, thus there is no special
311 * handling for multi-dimensional arrays.</p>
312 *
313 * <p>This method returns {@code null} for a {@code null} input array.</p>
314 *
315 * @param <T> the component type of the array
316 * @param array the array to shallow clone, may be {@code null}
317 * @return the cloned array, {@code null} if {@code null} input
318 */
319 public static <T> T[] clone(final T[] array) {
320 if (array == null) {
321 return null;
322 }
323 return array.clone();
324 }
325
326 /**
327 * <p>Clones an array returning a typecast result and handling
328 * {@code null}.</p>
329 *
330 * <p>This method returns {@code null} for a {@code null} input array.</p>
331 *
332 * @param array the array to clone, may be {@code null}
333 * @return the cloned array, {@code null} if {@code null} input
334 */
335 public static long[] clone(final long[] array) {
336 if (array == null) {
337 return null;
338 }
339 return array.clone();
340 }
341
342 /**
343 * <p>Clones an array returning a typecast result and handling
344 * {@code null}.</p>
345 *
346 * <p>This method returns {@code null} for a {@code null} input array.</p>
347 *
348 * @param array the array to clone, may be {@code null}
349 * @return the cloned array, {@code null} if {@code null} input
350 */
351 public static int[] clone(final int[] array) {
352 if (array == null) {
353 return null;
354 }
355 return array.clone();
356 }
357
358 /**
359 * <p>Clones an array returning a typecast result and handling
360 * {@code null}.</p>
361 *
362 * <p>This method returns {@code null} for a {@code null} input array.</p>
363 *
364 * @param array the array to clone, may be {@code null}
365 * @return the cloned array, {@code null} if {@code null} input
366 */
367 public static short[] clone(final short[] array) {
368 if (array == null) {
369 return null;
370 }
371 return array.clone();
372 }
373
374 /**
375 * <p>Clones an array returning a typecast result and handling
376 * {@code null}.</p>
377 *
378 * <p>This method returns {@code null} for a {@code null} input array.</p>
379 *
380 * @param array the array to clone, may be {@code null}
381 * @return the cloned array, {@code null} if {@code null} input
382 */
383 public static char[] clone(final char[] array) {
384 if (array == null) {
385 return null;
386 }
387 return array.clone();
388 }
389
390 /**
391 * <p>Clones an array returning a typecast result and handling
392 * {@code null}.</p>
393 *
394 * <p>This method returns {@code null} for a {@code null} input array.</p>
395 *
396 * @param array the array to clone, may be {@code null}
397 * @return the cloned array, {@code null} if {@code null} input
398 */
399 public static byte[] clone(final byte[] array) {
400 if (array == null) {
401 return null;
402 }
403 return array.clone();
404 }
405
406 /**
407 * <p>Clones an array returning a typecast result and handling
408 * {@code null}.</p>
409 *
410 * <p>This method returns {@code null} for a {@code null} input array.</p>
411 *
412 * @param array the array to clone, may be {@code null}
413 * @return the cloned array, {@code null} if {@code null} input
414 */
415 public static double[] clone(final double[] array) {
416 if (array == null) {
417 return null;
418 }
419 return array.clone();
420 }
421
422 /**
423 * <p>Clones an array returning a typecast result and handling
424 * {@code null}.</p>
425 *
426 * <p>This method returns {@code null} for a {@code null} input array.</p>
427 *
428 * @param array the array to clone, may be {@code null}
429 * @return the cloned array, {@code null} if {@code null} input
430 */
431 public static float[] clone(final float[] array) {
432 if (array == null) {
433 return null;
434 }
435 return array.clone();
436 }
437
438 /**
439 * <p>Clones an array returning a typecast result and handling
440 * {@code null}.</p>
441 *
442 * <p>This method returns {@code null} for a {@code null} input array.</p>
443 *
444 * @param array the array to clone, may be {@code null}
445 * @return the cloned array, {@code null} if {@code null} input
446 */
447 public static boolean[] clone(final boolean[] array) {
448 if (array == null) {
449 return null;
450 }
451 return array.clone();
452 }
453
454 // nullToEmpty
455 //-----------------------------------------------------------------------
456 /**
457 * <p>Defensive programming technique to change a {@code null}
458 * reference to an empty one.</p>
459 *
460 * <p>This method returns an empty array for a {@code null} input array.</p>
461 *
462 * <p>As a memory optimizing technique an empty array passed in will be overridden with
463 * the empty {@code public static} references in this class.</p>
464 *
465 * @param array the array to check for {@code null} or empty
466 * @return the same array, {@code public static} empty array if {@code null} or empty input
467 * @since 2.5
468 */
469 public static Object[] nullToEmpty(final Object[] array) {
470 if (array == null || array.length == 0) {
471 return EMPTY_OBJECT_ARRAY;
472 }
473 return array;
474 }
475
476 /**
477 * <p>Defensive programming technique to change a {@code null}
478 * reference to an empty one.</p>
479 *
480 * <p>This method returns an empty array for a {@code null} input array.</p>
481 *
482 * <p>As a memory optimizing technique an empty array passed in will be overridden with
483 * the empty {@code public static} references in this class.</p>
484 *
485 * @param array the array to check for {@code null} or empty
486 * @return the same array, {@code public static} empty array if {@code null} or empty input
487 * @since 2.5
488 */
489 public static String[] nullToEmpty(final String[] array) {
490 if (array == null || array.length == 0) {
491 return EMPTY_STRING_ARRAY;
492 }
493 return array;
494 }
495
496 /**
497 * <p>Defensive programming technique to change a {@code null}
498 * reference to an empty one.</p>
499 *
500 * <p>This method returns an empty array for a {@code null} input array.</p>
501 *
502 * <p>As a memory optimizing technique an empty array passed in will be overridden with
503 * the empty {@code public static} references in this class.</p>
504 *
505 * @param array the array to check for {@code null} or empty
506 * @return the same array, {@code public static} empty array if {@code null} or empty input
507 * @since 2.5
508 */
509 public static long[] nullToEmpty(final long[] array) {
510 if (array == null || array.length == 0) {
511 return EMPTY_LONG_ARRAY;
512 }
513 return array;
514 }
515
516 /**
517 * <p>Defensive programming technique to change a {@code null}
518 * reference to an empty one.</p>
519 *
520 * <p>This method returns an empty array for a {@code null} input array.</p>
521 *
522 * <p>As a memory optimizing technique an empty array passed in will be overridden with
523 * the empty {@code public static} references in this class.</p>
524 *
525 * @param array the array to check for {@code null} or empty
526 * @return the same array, {@code public static} empty array if {@code null} or empty input
527 * @since 2.5
528 */
529 public static int[] nullToEmpty(final int[] array) {
530 if (array == null || array.length == 0) {
531 return EMPTY_INT_ARRAY;
532 }
533 return array;
534 }
535
536 /**
537 * <p>Defensive programming technique to change a {@code null}
538 * reference to an empty one.</p>
539 *
540 * <p>This method returns an empty array for a {@code null} input array.</p>
541 *
542 * <p>As a memory optimizing technique an empty array passed in will be overridden with
543 * the empty {@code public static} references in this class.</p>
544 *
545 * @param array the array to check for {@code null} or empty
546 * @return the same array, {@code public static} empty array if {@code null} or empty input
547 * @since 2.5
548 */
549 public static short[] nullToEmpty(final short[] array) {
550 if (array == null || array.length == 0) {
551 return EMPTY_SHORT_ARRAY;
552 }
553 return array;
554 }
555
556 /**
557 * <p>Defensive programming technique to change a {@code null}
558 * reference to an empty one.</p>
559 *
560 * <p>This method returns an empty array for a {@code null} input array.</p>
561 *
562 * <p>As a memory optimizing technique an empty array passed in will be overridden with
563 * the empty {@code public static} references in this class.</p>
564 *
565 * @param array the array to check for {@code null} or empty
566 * @return the same array, {@code public static} empty array if {@code null} or empty input
567 * @since 2.5
568 */
569 public static char[] nullToEmpty(final char[] array) {
570 if (array == null || array.length == 0) {
571 return EMPTY_CHAR_ARRAY;
572 }
573 return array;
574 }
575
576 /**
577 * <p>Defensive programming technique to change a {@code null}
578 * reference to an empty one.</p>
579 *
580 * <p>This method returns an empty array for a {@code null} input array.</p>
581 *
582 * <p>As a memory optimizing technique an empty array passed in will be overridden with
583 * the empty {@code public static} references in this class.</p>
584 *
585 * @param array the array to check for {@code null} or empty
586 * @return the same array, {@code public static} empty array if {@code null} or empty input
587 * @since 2.5
588 */
589 public static byte[] nullToEmpty(final byte[] array) {
590 if (array == null || array.length == 0) {
591 return EMPTY_BYTE_ARRAY;
592 }
593 return array;
594 }
595
596 /**
597 * <p>Defensive programming technique to change a {@code null}
598 * reference to an empty one.</p>
599 *
600 * <p>This method returns an empty array for a {@code null} input array.</p>
601 *
602 * <p>As a memory optimizing technique an empty array passed in will be overridden with
603 * the empty {@code public static} references in this class.</p>
604 *
605 * @param array the array to check for {@code null} or empty
606 * @return the same array, {@code public static} empty array if {@code null} or empty input
607 * @since 2.5
608 */
609 public static double[] nullToEmpty(final double[] array) {
610 if (array == null || array.length == 0) {
611 return EMPTY_DOUBLE_ARRAY;
612 }
613 return array;
614 }
615
616 /**
617 * <p>Defensive programming technique to change a {@code null}
618 * reference to an empty one.</p>
619 *
620 * <p>This method returns an empty array for a {@code null} input array.</p>
621 *
622 * <p>As a memory optimizing technique an empty array passed in will be overridden with
623 * the empty {@code public static} references in this class.</p>
624 *
625 * @param array the array to check for {@code null} or empty
626 * @return the same array, {@code public static} empty array if {@code null} or empty input
627 * @since 2.5
628 */
629 public static float[] nullToEmpty(final float[] array) {
630 if (array == null || array.length == 0) {
631 return EMPTY_FLOAT_ARRAY;
632 }
633 return array;
634 }
635
636 /**
637 * <p>Defensive programming technique to change a {@code null}
638 * reference to an empty one.</p>
639 *
640 * <p>This method returns an empty array for a {@code null} input array.</p>
641 *
642 * <p>As a memory optimizing technique an empty array passed in will be overridden with
643 * the empty {@code public static} references in this class.</p>
644 *
645 * @param array the array to check for {@code null} or empty
646 * @return the same array, {@code public static} empty array if {@code null} or empty input
647 * @since 2.5
648 */
649 public static boolean[] nullToEmpty(final boolean[] array) {
650 if (array == null || array.length == 0) {
651 return EMPTY_BOOLEAN_ARRAY;
652 }
653 return array;
654 }
655
656 /**
657 * <p>Defensive programming technique to change a {@code null}
658 * reference to an empty one.</p>
659 *
660 * <p>This method returns an empty array for a {@code null} input array.</p>
661 *
662 * <p>As a memory optimizing technique an empty array passed in will be overridden with
663 * the empty {@code public static} references in this class.</p>
664 *
665 * @param array the array to check for {@code null} or empty
666 * @return the same array, {@code public static} empty array if {@code null} or empty input
667 * @since 2.5
668 */
669 public static Long[] nullToEmpty(final Long[] array) {
670 if (array == null || array.length == 0) {
671 return EMPTY_LONG_OBJECT_ARRAY;
672 }
673 return array;
674 }
675
676 /**
677 * <p>Defensive programming technique to change a {@code null}
678 * reference to an empty one.</p>
679 *
680 * <p>This method returns an empty array for a {@code null} input array.</p>
681 *
682 * <p>As a memory optimizing technique an empty array passed in will be overridden with
683 * the empty {@code public static} references in this class.</p>
684 *
685 * @param array the array to check for {@code null} or empty
686 * @return the same array, {@code public static} empty array if {@code null} or empty input
687 * @since 2.5
688 */
689 public static Integer[] nullToEmpty(final Integer[] array) {
690 if (array == null || array.length == 0) {
691 return EMPTY_INTEGER_OBJECT_ARRAY;
692 }
693 return array;
694 }
695
696 /**
697 * <p>Defensive programming technique to change a {@code null}
698 * reference to an empty one.</p>
699 *
700 * <p>This method returns an empty array for a {@code null} input array.</p>
701 *
702 * <p>As a memory optimizing technique an empty array passed in will be overridden with
703 * the empty {@code public static} references in this class.</p>
704 *
705 * @param array the array to check for {@code null} or empty
706 * @return the same array, {@code public static} empty array if {@code null} or empty input
707 * @since 2.5
708 */
709 public static Short[] nullToEmpty(final Short[] array) {
710 if (array == null || array.length == 0) {
711 return EMPTY_SHORT_OBJECT_ARRAY;
712 }
713 return array;
714 }
715
716 /**
717 * <p>Defensive programming technique to change a {@code null}
718 * reference to an empty one.</p>
719 *
720 * <p>This method returns an empty array for a {@code null} input array.</p>
721 *
722 * <p>As a memory optimizing technique an empty array passed in will be overridden with
723 * the empty {@code public static} references in this class.</p>
724 *
725 * @param array the array to check for {@code null} or empty
726 * @return the same array, {@code public static} empty array if {@code null} or empty input
727 * @since 2.5
728 */
729 public static Character[] nullToEmpty(final Character[] array) {
730 if (array == null || array.length == 0) {
731 return EMPTY_CHARACTER_OBJECT_ARRAY;
732 }
733 return array;
734 }
735
736 /**
737 * <p>Defensive programming technique to change a {@code null}
738 * reference to an empty one.</p>
739 *
740 * <p>This method returns an empty array for a {@code null} input array.</p>
741 *
742 * <p>As a memory optimizing technique an empty array passed in will be overridden with
743 * the empty {@code public static} references in this class.</p>
744 *
745 * @param array the array to check for {@code null} or empty
746 * @return the same array, {@code public static} empty array if {@code null} or empty input
747 * @since 2.5
748 */
749 public static Byte[] nullToEmpty(final Byte[] array) {
750 if (array == null || array.length == 0) {
751 return EMPTY_BYTE_OBJECT_ARRAY;
752 }
753 return array;
754 }
755
756 /**
757 * <p>Defensive programming technique to change a {@code null}
758 * reference to an empty one.</p>
759 *
760 * <p>This method returns an empty array for a {@code null} input array.</p>
761 *
762 * <p>As a memory optimizing technique an empty array passed in will be overridden with
763 * the empty {@code public static} references in this class.</p>
764 *
765 * @param array the array to check for {@code null} or empty
766 * @return the same array, {@code public static} empty array if {@code null} or empty input
767 * @since 2.5
768 */
769 public static Double[] nullToEmpty(final Double[] array) {
770 if (array == null || array.length == 0) {
771 return EMPTY_DOUBLE_OBJECT_ARRAY;
772 }
773 return array;
774 }
775
776 /**
777 * <p>Defensive programming technique to change a {@code null}
778 * reference to an empty one.</p>
779 *
780 * <p>This method returns an empty array for a {@code null} input array.</p>
781 *
782 * <p>As a memory optimizing technique an empty array passed in will be overridden with
783 * the empty {@code public static} references in this class.</p>
784 *
785 * @param array the array to check for {@code null} or empty
786 * @return the same array, {@code public static} empty array if {@code null} or empty input
787 * @since 2.5
788 */
789 public static Float[] nullToEmpty(final Float[] array) {
790 if (array == null || array.length == 0) {
791 return EMPTY_FLOAT_OBJECT_ARRAY;
792 }
793 return array;
794 }
795
796 /**
797 * <p>Defensive programming technique to change a {@code null}
798 * reference to an empty one.</p>
799 *
800 * <p>This method returns an empty array for a {@code null} input array.</p>
801 *
802 * <p>As a memory optimizing technique an empty array passed in will be overridden with
803 * the empty {@code public static} references in this class.</p>
804 *
805 * @param array the array to check for {@code null} or empty
806 * @return the same array, {@code public static} empty array if {@code null} or empty input
807 * @since 2.5
808 */
809 public static Boolean[] nullToEmpty(final Boolean[] array) {
810 if (array == null || array.length == 0) {
811 return EMPTY_BOOLEAN_OBJECT_ARRAY;
812 }
813 return array;
814 }
815
816 // Subarrays
817 //-----------------------------------------------------------------------
818 /**
819 * <p>Produces a new array containing the elements between
820 * the start and end indices.</p>
821 *
822 * <p>The start index is inclusive, the end index exclusive.
823 * Null array input produces null output.</p>
824 *
825 * <p>The component type of the subarray is always the same as
826 * that of the input array. Thus, if the input is an array of type
827 * {@code Date}, the following usage is envisaged:</p>
828 *
829 * <pre>
830 * Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
831 * </pre>
832 *
833 * @param <T> the component type of the array
834 * @param array the array
835 * @param startIndexInclusive the starting index. Undervalue (<0)
836 * is promoted to 0, overvalue (>array.length) results
837 * in an empty array.
838 * @param endIndexExclusive elements up to endIndex-1 are present in the
839 * returned subarray. Undervalue (< startIndex) produces
840 * empty array, overvalue (>array.length) is demoted to
841 * array length.
842 * @return a new array containing the elements between
843 * the start and end indices.
844 * @since 2.1
845 */
846 public static <T> T[] subarray(final T[] array, int startIndexInclusive, int endIndexExclusive) {
847 if (array == null) {
848 return null;
849 }
850 if (startIndexInclusive < 0) {
851 startIndexInclusive = 0;
852 }
853 if (endIndexExclusive > array.length) {
854 endIndexExclusive = array.length;
855 }
856 final int newSize = endIndexExclusive - startIndexInclusive;
857 final Class<?> type = array.getClass().getComponentType();
858 if (newSize <= 0) {
859 @SuppressWarnings("unchecked") // OK, because array is of type T
860 final T[] emptyArray = (T[]) Array.newInstance(type, 0);
861 return emptyArray;
862 }
863 @SuppressWarnings("unchecked") // OK, because array is of type T
864 final
865 T[] subarray = (T[]) Array.newInstance(type, newSize);
866 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
867 return subarray;
868 }
869
870 /**
871 * <p>Produces a new {@code long} array containing the elements
872 * between the start and end indices.</p>
873 *
874 * <p>The start index is inclusive, the end index exclusive.
875 * Null array input produces null output.</p>
876 *
877 * @param array the array
878 * @param startIndexInclusive the starting index. Undervalue (<0)
879 * is promoted to 0, overvalue (>array.length) results
880 * in an empty array.
881 * @param endIndexExclusive elements up to endIndex-1 are present in the
882 * returned subarray. Undervalue (< startIndex) produces
883 * empty array, overvalue (>array.length) is demoted to
884 * array length.
885 * @return a new array containing the elements between
886 * the start and end indices.
887 * @since 2.1
888 */
889 public static long[] subarray(final long[] array, int startIndexInclusive, int endIndexExclusive) {
890 if (array == null) {
891 return null;
892 }
893 if (startIndexInclusive < 0) {
894 startIndexInclusive = 0;
895 }
896 if (endIndexExclusive > array.length) {
897 endIndexExclusive = array.length;
898 }
899 final int newSize = endIndexExclusive - startIndexInclusive;
900 if (newSize <= 0) {
901 return EMPTY_LONG_ARRAY;
902 }
903
904 final long[] subarray = new long[newSize];
905 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
906 return subarray;
907 }
908
909 /**
910 * <p>Produces a new {@code int} array containing the elements
911 * between the start and end indices.</p>
912 *
913 * <p>The start index is inclusive, the end index exclusive.
914 * Null array input produces null output.</p>
915 *
916 * @param array the array
917 * @param startIndexInclusive the starting index. Undervalue (<0)
918 * is promoted to 0, overvalue (>array.length) results
919 * in an empty array.
920 * @param endIndexExclusive elements up to endIndex-1 are present in the
921 * returned subarray. Undervalue (< startIndex) produces
922 * empty array, overvalue (>array.length) is demoted to
923 * array length.
924 * @return a new array containing the elements between
925 * the start and end indices.
926 * @since 2.1
927 */
928 public static int[] subarray(final int[] array, int startIndexInclusive, int endIndexExclusive) {
929 if (array == null) {
930 return null;
931 }
932 if (startIndexInclusive < 0) {
933 startIndexInclusive = 0;
934 }
935 if (endIndexExclusive > array.length) {
936 endIndexExclusive = array.length;
937 }
938 final int newSize = endIndexExclusive - startIndexInclusive;
939 if (newSize <= 0) {
940 return EMPTY_INT_ARRAY;
941 }
942
943 final int[] subarray = new int[newSize];
944 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
945 return subarray;
946 }
947
948 /**
949 * <p>Produces a new {@code short} array containing the elements
950 * between the start and end indices.</p>
951 *
952 * <p>The start index is inclusive, the end index exclusive.
953 * Null array input produces null output.</p>
954 *
955 * @param array the array
956 * @param startIndexInclusive the starting index. Undervalue (<0)
957 * is promoted to 0, overvalue (>array.length) results
958 * in an empty array.
959 * @param endIndexExclusive elements up to endIndex-1 are present in the
960 * returned subarray. Undervalue (< startIndex) produces
961 * empty array, overvalue (>array.length) is demoted to
962 * array length.
963 * @return a new array containing the elements between
964 * the start and end indices.
965 * @since 2.1
966 */
967 public static short[] subarray(final short[] array, int startIndexInclusive, int endIndexExclusive) {
968 if (array == null) {
969 return null;
970 }
971 if (startIndexInclusive < 0) {
972 startIndexInclusive = 0;
973 }
974 if (endIndexExclusive > array.length) {
975 endIndexExclusive = array.length;
976 }
977 final int newSize = endIndexExclusive - startIndexInclusive;
978 if (newSize <= 0) {
979 return EMPTY_SHORT_ARRAY;
980 }
981
982 final short[] subarray = new short[newSize];
983 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
984 return subarray;
985 }
986
987 /**
988 * <p>Produces a new {@code char} array containing the elements
989 * between the start and end indices.</p>
990 *
991 * <p>The start index is inclusive, the end index exclusive.
992 * Null array input produces null output.</p>
993 *
994 * @param array the array
995 * @param startIndexInclusive the starting index. Undervalue (<0)
996 * is promoted to 0, overvalue (>array.length) results
997 * in an empty array.
998 * @param endIndexExclusive elements up to endIndex-1 are present in the
999 * returned subarray. Undervalue (< startIndex) produces
1000 * empty array, overvalue (>array.length) is demoted to
1001 * array length.
1002 * @return a new array containing the elements between
1003 * the start and end indices.
1004 * @since 2.1
1005 */
1006 public static char[] subarray(final char[] array, int startIndexInclusive, int endIndexExclusive) {
1007 if (array == null) {
1008 return null;
1009 }
1010 if (startIndexInclusive < 0) {
1011 startIndexInclusive = 0;
1012 }
1013 if (endIndexExclusive > array.length) {
1014 endIndexExclusive = array.length;
1015 }
1016 final int newSize = endIndexExclusive - startIndexInclusive;
1017 if (newSize <= 0) {
1018 return EMPTY_CHAR_ARRAY;
1019 }
1020
1021 final char[] subarray = new char[newSize];
1022 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1023 return subarray;
1024 }
1025
1026 /**
1027 * <p>Produces a new {@code byte} array containing the elements
1028 * between the start and end indices.</p>
1029 *
1030 * <p>The start index is inclusive, the end index exclusive.
1031 * Null array input produces null output.</p>
1032 *
1033 * @param array the array
1034 * @param startIndexInclusive the starting index. Undervalue (<0)
1035 * is promoted to 0, overvalue (>array.length) results
1036 * in an empty array.
1037 * @param endIndexExclusive elements up to endIndex-1 are present in the
1038 * returned subarray. Undervalue (< startIndex) produces
1039 * empty array, overvalue (>array.length) is demoted to
1040 * array length.
1041 * @return a new array containing the elements between
1042 * the start and end indices.
1043 * @since 2.1
1044 */
1045 public static byte[] subarray(final byte[] array, int startIndexInclusive, int endIndexExclusive) {
1046 if (array == null) {
1047 return null;
1048 }
1049 if (startIndexInclusive < 0) {
1050 startIndexInclusive = 0;
1051 }
1052 if (endIndexExclusive > array.length) {
1053 endIndexExclusive = array.length;
1054 }
1055 final int newSize = endIndexExclusive - startIndexInclusive;
1056 if (newSize <= 0) {
1057 return EMPTY_BYTE_ARRAY;
1058 }
1059
1060 final byte[] subarray = new byte[newSize];
1061 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1062 return subarray;
1063 }
1064
1065 /**
1066 * <p>Produces a new {@code double} array containing the elements
1067 * between the start and end indices.</p>
1068 *
1069 * <p>The start index is inclusive, the end index exclusive.
1070 * Null array input produces null output.</p>
1071 *
1072 * @param array the array
1073 * @param startIndexInclusive the starting index. Undervalue (<0)
1074 * is promoted to 0, overvalue (>array.length) results
1075 * in an empty array.
1076 * @param endIndexExclusive elements up to endIndex-1 are present in the
1077 * returned subarray. Undervalue (< startIndex) produces
1078 * empty array, overvalue (>array.length) is demoted to
1079 * array length.
1080 * @return a new array containing the elements between
1081 * the start and end indices.
1082 * @since 2.1
1083 */
1084 public static double[] subarray(final double[] array, int startIndexInclusive, int endIndexExclusive) {
1085 if (array == null) {
1086 return null;
1087 }
1088 if (startIndexInclusive < 0) {
1089 startIndexInclusive = 0;
1090 }
1091 if (endIndexExclusive > array.length) {
1092 endIndexExclusive = array.length;
1093 }
1094 final int newSize = endIndexExclusive - startIndexInclusive;
1095 if (newSize <= 0) {
1096 return EMPTY_DOUBLE_ARRAY;
1097 }
1098
1099 final double[] subarray = new double[newSize];
1100 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1101 return subarray;
1102 }
1103
1104 /**
1105 * <p>Produces a new {@code float} array containing the elements
1106 * between the start and end indices.</p>
1107 *
1108 * <p>The start index is inclusive, the end index exclusive.
1109 * Null array input produces null output.</p>
1110 *
1111 * @param array the array
1112 * @param startIndexInclusive the starting index. Undervalue (<0)
1113 * is promoted to 0, overvalue (>array.length) results
1114 * in an empty array.
1115 * @param endIndexExclusive elements up to endIndex-1 are present in the
1116 * returned subarray. Undervalue (< startIndex) produces
1117 * empty array, overvalue (>array.length) is demoted to
1118 * array length.
1119 * @return a new array containing the elements between
1120 * the start and end indices.
1121 * @since 2.1
1122 */
1123 public static float[] subarray(final float[] array, int startIndexInclusive, int endIndexExclusive) {
1124 if (array == null) {
1125 return null;
1126 }
1127 if (startIndexInclusive < 0) {
1128 startIndexInclusive = 0;
1129 }
1130 if (endIndexExclusive > array.length) {
1131 endIndexExclusive = array.length;
1132 }
1133 final int newSize = endIndexExclusive - startIndexInclusive;
1134 if (newSize <= 0) {
1135 return EMPTY_FLOAT_ARRAY;
1136 }
1137
1138 final float[] subarray = new float[newSize];
1139 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1140 return subarray;
1141 }
1142
1143 /**
1144 * <p>Produces a new {@code boolean} array containing the elements
1145 * between the start and end indices.</p>
1146 *
1147 * <p>The start index is inclusive, the end index exclusive.
1148 * Null array input produces null output.</p>
1149 *
1150 * @param array the array
1151 * @param startIndexInclusive the starting index. Undervalue (<0)
1152 * is promoted to 0, overvalue (>array.length) results
1153 * in an empty array.
1154 * @param endIndexExclusive elements up to endIndex-1 are present in the
1155 * returned subarray. Undervalue (< startIndex) produces
1156 * empty array, overvalue (>array.length) is demoted to
1157 * array length.
1158 * @return a new array containing the elements between
1159 * the start and end indices.
1160 * @since 2.1
1161 */
1162 public static boolean[] subarray(final boolean[] array, int startIndexInclusive, int endIndexExclusive) {
1163 if (array == null) {
1164 return null;
1165 }
1166 if (startIndexInclusive < 0) {
1167 startIndexInclusive = 0;
1168 }
1169 if (endIndexExclusive > array.length) {
1170 endIndexExclusive = array.length;
1171 }
1172 final int newSize = endIndexExclusive - startIndexInclusive;
1173 if (newSize <= 0) {
1174 return EMPTY_BOOLEAN_ARRAY;
1175 }
1176
1177 final boolean[] subarray = new boolean[newSize];
1178 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
1179 return subarray;
1180 }
1181
1182 // Is same length
1183 //-----------------------------------------------------------------------
1184 /**
1185 * <p>Checks whether two arrays are the same length, treating
1186 * {@code null} arrays as length {@code 0}.
1187 *
1188 * <p>Any multi-dimensional aspects of the arrays are ignored.</p>
1189 *
1190 * @param array1 the first array, may be {@code null}
1191 * @param array2 the second array, may be {@code null}
1192 * @return {@code true} if length of arrays matches, treating
1193 * {@code null} as an empty array
1194 */
1195 public static boolean isSameLength(final Object[] array1, final Object[] array2) {
1196 if ((array1 == null && array2 != null && array2.length > 0) ||
1197 (array2 == null && array1 != null && array1.length > 0) ||
1198 (array1 != null && array2 != null && array1.length != array2.length)) {
1199 return false;
1200 }
1201 return true;
1202 }
1203
1204 /**
1205 * <p>Checks whether two arrays are the same length, treating
1206 * {@code null} arrays as length {@code 0}.</p>
1207 *
1208 * @param array1 the first array, may be {@code null}
1209 * @param array2 the second array, may be {@code null}
1210 * @return {@code true} if length of arrays matches, treating
1211 * {@code null} as an empty array
1212 */
1213 public static boolean isSameLength(final long[] array1, final long[] array2) {
1214 if ((array1 == null && array2 != null && array2.length > 0) ||
1215 (array2 == null && array1 != null && array1.length > 0) ||
1216 (array1 != null && array2 != null && array1.length != array2.length)) {
1217 return false;
1218 }
1219 return true;
1220 }
1221
1222 /**
1223 * <p>Checks whether two arrays are the same length, treating
1224 * {@code null} arrays as length {@code 0}.</p>
1225 *
1226 * @param array1 the first array, may be {@code null}
1227 * @param array2 the second array, may be {@code null}
1228 * @return {@code true} if length of arrays matches, treating
1229 * {@code null} as an empty array
1230 */
1231 public static boolean isSameLength(final int[] array1, final int[] array2) {
1232 if ((array1 == null && array2 != null && array2.length > 0) ||
1233 (array2 == null && array1 != null && array1.length > 0) ||
1234 (array1 != null && array2 != null && array1.length != array2.length)) {
1235 return false;
1236 }
1237 return true;
1238 }
1239
1240 /**
1241 * <p>Checks whether two arrays are the same length, treating
1242 * {@code null} arrays as length {@code 0}.</p>
1243 *
1244 * @param array1 the first array, may be {@code null}
1245 * @param array2 the second array, may be {@code null}
1246 * @return {@code true} if length of arrays matches, treating
1247 * {@code null} as an empty array
1248 */
1249 public static boolean isSameLength(final short[] array1, final short[] array2) {
1250 if ((array1 == null && array2 != null && array2.length > 0) ||
1251 (array2 == null && array1 != null && array1.length > 0) ||
1252 (array1 != null && array2 != null && array1.length != array2.length)) {
1253 return false;
1254 }
1255 return true;
1256 }
1257
1258 /**
1259 * <p>Checks whether two arrays are the same length, treating
1260 * {@code null} arrays as length {@code 0}.</p>
1261 *
1262 * @param array1 the first array, may be {@code null}
1263 * @param array2 the second array, may be {@code null}
1264 * @return {@code true} if length of arrays matches, treating
1265 * {@code null} as an empty array
1266 */
1267 public static boolean isSameLength(final char[] array1, final char[] array2) {
1268 if ((array1 == null && array2 != null && array2.length > 0) ||
1269 (array2 == null && array1 != null && array1.length > 0) ||
1270 (array1 != null && array2 != null && array1.length != array2.length)) {
1271 return false;
1272 }
1273 return true;
1274 }
1275
1276 /**
1277 * <p>Checks whether two arrays are the same length, treating
1278 * {@code null} arrays as length {@code 0}.</p>
1279 *
1280 * @param array1 the first array, may be {@code null}
1281 * @param array2 the second array, may be {@code null}
1282 * @return {@code true} if length of arrays matches, treating
1283 * {@code null} as an empty array
1284 */
1285 public static boolean isSameLength(final byte[] array1, final byte[] array2) {
1286 if ((array1 == null && array2 != null && array2.length > 0) ||
1287 (array2 == null && array1 != null && array1.length > 0) ||
1288 (array1 != null && array2 != null && array1.length != array2.length)) {
1289 return false;
1290 }
1291 return true;
1292 }
1293
1294 /**
1295 * <p>Checks whether two arrays are the same length, treating
1296 * {@code null} arrays as length {@code 0}.</p>
1297 *
1298 * @param array1 the first array, may be {@code null}
1299 * @param array2 the second array, may be {@code null}
1300 * @return {@code true} if length of arrays matches, treating
1301 * {@code null} as an empty array
1302 */
1303 public static boolean isSameLength(final double[] array1, final double[] array2) {
1304 if ((array1 == null && array2 != null && array2.length > 0) ||
1305 (array2 == null && array1 != null && array1.length > 0) ||
1306 (array1 != null && array2 != null && array1.length != array2.length)) {
1307 return false;
1308 }
1309 return true;
1310 }
1311
1312 /**
1313 * <p>Checks whether two arrays are the same length, treating
1314 * {@code null} arrays as length {@code 0}.</p>
1315 *
1316 * @param array1 the first array, may be {@code null}
1317 * @param array2 the second array, may be {@code null}
1318 * @return {@code true} if length of arrays matches, treating
1319 * {@code null} as an empty array
1320 */
1321 public static boolean isSameLength(final float[] array1, final float[] array2) {
1322 if ((array1 == null && array2 != null && array2.length > 0) ||
1323 (array2 == null && array1 != null && array1.length > 0) ||
1324 (array1 != null && array2 != null && array1.length != array2.length)) {
1325 return false;
1326 }
1327 return true;
1328 }
1329
1330 /**
1331 * <p>Checks whether two arrays are the same length, treating
1332 * {@code null} arrays as length {@code 0}.</p>
1333 *
1334 * @param array1 the first array, may be {@code null}
1335 * @param array2 the second array, may be {@code null}
1336 * @return {@code true} if length of arrays matches, treating
1337 * {@code null} as an empty array
1338 */
1339 public static boolean isSameLength(final boolean[] array1, final boolean[] array2) {
1340 if ((array1 == null && array2 != null && array2.length > 0) ||
1341 (array2 == null && array1 != null && array1.length > 0) ||
1342 (array1 != null && array2 != null && array1.length != array2.length)) {
1343 return false;
1344 }
1345 return true;
1346 }
1347
1348 //-----------------------------------------------------------------------
1349 /**
1350 * <p>Returns the length of the specified array.
1351 * This method can deal with {@code Object} arrays and with primitive arrays.</p>
1352 *
1353 * <p>If the input array is {@code null}, {@code 0} is returned.</p>
1354 *
1355 * <pre>
1356 * ArrayUtils.getLength(null) = 0
1357 * ArrayUtils.getLength([]) = 0
1358 * ArrayUtils.getLength([null]) = 1
1359 * ArrayUtils.getLength([true, false]) = 2
1360 * ArrayUtils.getLength([1, 2, 3]) = 3
1361 * ArrayUtils.getLength(["a", "b", "c"]) = 3
1362 * </pre>
1363 *
1364 * @param array the array to retrieve the length from, may be null
1365 * @return The length of the array, or {@code 0} if the array is {@code null}
1366 * @throws IllegalArgumentException if the object argument is not an array.
1367 * @since 2.1
1368 */
1369 public static int getLength(final Object array) {
1370 if (array == null) {
1371 return 0;
1372 }
1373 return Array.getLength(array);
1374 }
1375
1376 /**
1377 * <p>Checks whether two arrays are the same type taking into account
1378 * multi-dimensional arrays.</p>
1379 *
1380 * @param array1 the first array, must not be {@code null}
1381 * @param array2 the second array, must not be {@code null}
1382 * @return {@code true} if type of arrays matches
1383 * @throws IllegalArgumentException if either array is {@code null}
1384 */
1385 public static boolean isSameType(final Object array1, final Object array2) {
1386 if (array1 == null || array2 == null) {
1387 throw new IllegalArgumentException("The Array must not be null");
1388 }
1389 return array1.getClass().getName().equals(array2.getClass().getName());
1390 }
1391
1392 // Reverse
1393 //-----------------------------------------------------------------------
1394 /**
1395 * <p>Reverses the order of the given array.</p>
1396 *
1397 * <p>There is no special handling for multi-dimensional arrays.</p>
1398 *
1399 * <p>This method does nothing for a {@code null} input array.</p>
1400 *
1401 * @param array the array to reverse, may be {@code null}
1402 */
1403 public static void reverse(final Object[] array) {
1404 if (array == null) {
1405 return;
1406 }
1407 int i = 0;
1408 int j = array.length - 1;
1409 Object tmp;
1410 while (j > i) {
1411 tmp = array[j];
1412 array[j] = array[i];
1413 array[i] = tmp;
1414 j--;
1415 i++;
1416 }
1417 }
1418
1419 /**
1420 * <p>Reverses the order of the given array.</p>
1421 *
1422 * <p>This method does nothing for a {@code null} input array.</p>
1423 *
1424 * @param array the array to reverse, may be {@code null}
1425 */
1426 public static void reverse(final long[] array) {
1427 if (array == null) {
1428 return;
1429 }
1430 int i = 0;
1431 int j = array.length - 1;
1432 long tmp;
1433 while (j > i) {
1434 tmp = array[j];
1435 array[j] = array[i];
1436 array[i] = tmp;
1437 j--;
1438 i++;
1439 }
1440 }
1441
1442 /**
1443 * <p>Reverses the order of the given array.</p>
1444 *
1445 * <p>This method does nothing for a {@code null} input array.</p>
1446 *
1447 * @param array the array to reverse, may be {@code null}
1448 */
1449 public static void reverse(final int[] array) {
1450 if (array == null) {
1451 return;
1452 }
1453 int i = 0;
1454 int j = array.length - 1;
1455 int tmp;
1456 while (j > i) {
1457 tmp = array[j];
1458 array[j] = array[i];
1459 array[i] = tmp;
1460 j--;
1461 i++;
1462 }
1463 }
1464
1465 /**
1466 * <p>Reverses the order of the given array.</p>
1467 *
1468 * <p>This method does nothing for a {@code null} input array.</p>
1469 *
1470 * @param array the array to reverse, may be {@code null}
1471 */
1472 public static void reverse(final short[] array) {
1473 if (array == null) {
1474 return;
1475 }
1476 int i = 0;
1477 int j = array.length - 1;
1478 short tmp;
1479 while (j > i) {
1480 tmp = array[j];
1481 array[j] = array[i];
1482 array[i] = tmp;
1483 j--;
1484 i++;
1485 }
1486 }
1487
1488 /**
1489 * <p>Reverses the order of the given array.</p>
1490 *
1491 * <p>This method does nothing for a {@code null} input array.</p>
1492 *
1493 * @param array the array to reverse, may be {@code null}
1494 */
1495 public static void reverse(final char[] array) {
1496 if (array == null) {
1497 return;
1498 }
1499 int i = 0;
1500 int j = array.length - 1;
1501 char tmp;
1502 while (j > i) {
1503 tmp = array[j];
1504 array[j] = array[i];
1505 array[i] = tmp;
1506 j--;
1507 i++;
1508 }
1509 }
1510
1511 /**
1512 * <p>Reverses the order of the given array.</p>
1513 *
1514 * <p>This method does nothing for a {@code null} input array.</p>
1515 *
1516 * @param array the array to reverse, may be {@code null}
1517 */
1518 public static void reverse(final byte[] array) {
1519 if (array == null) {
1520 return;
1521 }
1522 int i = 0;
1523 int j = array.length - 1;
1524 byte tmp;
1525 while (j > i) {
1526 tmp = array[j];
1527 array[j] = array[i];
1528 array[i] = tmp;
1529 j--;
1530 i++;
1531 }
1532 }
1533
1534 /**
1535 * <p>Reverses the order of the given array.</p>
1536 *
1537 * <p>This method does nothing for a {@code null} input array.</p>
1538 *
1539 * @param array the array to reverse, may be {@code null}
1540 */
1541 public static void reverse(final double[] array) {
1542 if (array == null) {
1543 return;
1544 }
1545 int i = 0;
1546 int j = array.length - 1;
1547 double tmp;
1548 while (j > i) {
1549 tmp = array[j];
1550 array[j] = array[i];
1551 array[i] = tmp;
1552 j--;
1553 i++;
1554 }
1555 }
1556
1557 /**
1558 * <p>Reverses the order of the given array.</p>
1559 *
1560 * <p>This method does nothing for a {@code null} input array.</p>
1561 *
1562 * @param array the array to reverse, may be {@code null}
1563 */
1564 public static void reverse(final float[] array) {
1565 if (array == null) {
1566 return;
1567 }
1568 int i = 0;
1569 int j = array.length - 1;
1570 float tmp;
1571 while (j > i) {
1572 tmp = array[j];
1573 array[j] = array[i];
1574 array[i] = tmp;
1575 j--;
1576 i++;
1577 }
1578 }
1579
1580 /**
1581 * <p>Reverses the order of the given array.</p>
1582 *
1583 * <p>This method does nothing for a {@code null} input array.</p>
1584 *
1585 * @param array the array to reverse, may be {@code null}
1586 */
1587 public static void reverse(final boolean[] array) {
1588 if (array == null) {
1589 return;
1590 }
1591 int i = 0;
1592 int j = array.length - 1;
1593 boolean tmp;
1594 while (j > i) {
1595 tmp = array[j];
1596 array[j] = array[i];
1597 array[i] = tmp;
1598 j--;
1599 i++;
1600 }
1601 }
1602
1603 // IndexOf search
1604 // ----------------------------------------------------------------------
1605
1606 // Object IndexOf
1607 //-----------------------------------------------------------------------
1608 /**
1609 * <p>Finds the index of the given object in the array.</p>
1610 *
1611 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1612 *
1613 * @param array the array to search through for the object, may be {@code null}
1614 * @param objectToFind the object to find, may be {@code null}
1615 * @return the index of the object within the array,
1616 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1617 */
1618 public static int indexOf(final Object[] array, final Object objectToFind) {
1619 return indexOf(array, objectToFind, 0);
1620 }
1621
1622 /**
1623 * <p>Finds the index of the given object in the array starting at the given index.</p>
1624 *
1625 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1626 *
1627 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1628 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
1629 *
1630 * @param array the array to search through for the object, may be {@code null}
1631 * @param objectToFind the object to find, may be {@code null}
1632 * @param startIndex the index to start searching at
1633 * @return the index of the object within the array starting at the index,
1634 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1635 */
1636 public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
1637 if (array == null) {
1638 return INDEX_NOT_FOUND;
1639 }
1640 if (startIndex < 0) {
1641 startIndex = 0;
1642 }
1643 if (objectToFind == null) {
1644 for (int i = startIndex; i < array.length; i++) {
1645 if (array[i] == null) {
1646 return i;
1647 }
1648 }
1649 } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
1650 for (int i = startIndex; i < array.length; i++) {
1651 if (objectToFind.equals(array[i])) {
1652 return i;
1653 }
1654 }
1655 }
1656 return INDEX_NOT_FOUND;
1657 }
1658
1659 /**
1660 * <p>Finds the last index of the given object within the array.</p>
1661 *
1662 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1663 *
1664 * @param array the array to travers backwords looking for the object, may be {@code null}
1665 * @param objectToFind the object to find, may be {@code null}
1666 * @return the last index of the object within the array,
1667 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1668 */
1669 public static int lastIndexOf(final Object[] array, final Object objectToFind) {
1670 return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
1671 }
1672
1673 /**
1674 * <p>Finds the last index of the given object in the array starting at the given index.</p>
1675 *
1676 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1677 *
1678 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
1679 * the array length will search from the end of the array.</p>
1680 *
1681 * @param array the array to traverse for looking for the object, may be {@code null}
1682 * @param objectToFind the object to find, may be {@code null}
1683 * @param startIndex the start index to travers backwards from
1684 * @return the last index of the object within the array,
1685 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1686 */
1687 public static int lastIndexOf(final Object[] array, final Object objectToFind, int startIndex) {
1688 if (array == null) {
1689 return INDEX_NOT_FOUND;
1690 }
1691 if (startIndex < 0) {
1692 return INDEX_NOT_FOUND;
1693 } else if (startIndex >= array.length) {
1694 startIndex = array.length - 1;
1695 }
1696 if (objectToFind == null) {
1697 for (int i = startIndex; i >= 0; i--) {
1698 if (array[i] == null) {
1699 return i;
1700 }
1701 }
1702 } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
1703 for (int i = startIndex; i >= 0; i--) {
1704 if (objectToFind.equals(array[i])) {
1705 return i;
1706 }
1707 }
1708 }
1709 return INDEX_NOT_FOUND;
1710 }
1711
1712 /**
1713 * <p>Checks if the object is in the given array.</p>
1714 *
1715 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
1716 *
1717 * @param array the array to search through
1718 * @param objectToFind the object to find
1719 * @return {@code true} if the array contains the object
1720 */
1721 public static boolean contains(final Object[] array, final Object objectToFind) {
1722 return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
1723 }
1724
1725 // long IndexOf
1726 //-----------------------------------------------------------------------
1727 /**
1728 * <p>Finds the index of the given value in the array.</p>
1729 *
1730 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1731 *
1732 * @param array the array to search through for the object, may be {@code null}
1733 * @param valueToFind the value to find
1734 * @return the index of the value within the array,
1735 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1736 */
1737 public static int indexOf(final long[] array, final long valueToFind) {
1738 return indexOf(array, valueToFind, 0);
1739 }
1740
1741 /**
1742 * <p>Finds the index of the given value in the array starting at the given index.</p>
1743 *
1744 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1745 *
1746 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1747 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
1748 *
1749 * @param array the array to search through for the object, may be {@code null}
1750 * @param valueToFind the value to find
1751 * @param startIndex the index to start searching at
1752 * @return the index of the value within the array,
1753 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1754 */
1755 public static int indexOf(final long[] array, final long valueToFind, int startIndex) {
1756 if (array == null) {
1757 return INDEX_NOT_FOUND;
1758 }
1759 if (startIndex < 0) {
1760 startIndex = 0;
1761 }
1762 for (int i = startIndex; i < array.length; i++) {
1763 if (valueToFind == array[i]) {
1764 return i;
1765 }
1766 }
1767 return INDEX_NOT_FOUND;
1768 }
1769
1770 /**
1771 * <p>Finds the last index of the given value within the array.</p>
1772 *
1773 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1774 *
1775 * @param array the array to travers backwords looking for the object, may be {@code null}
1776 * @param valueToFind the object to find
1777 * @return the last index of the value within the array,
1778 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1779 */
1780 public static int lastIndexOf(final long[] array, final long valueToFind) {
1781 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1782 }
1783
1784 /**
1785 * <p>Finds the last index of the given value in the array starting at the given index.</p>
1786 *
1787 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1788 *
1789 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
1790 * array length will search from the end of the array.</p>
1791 *
1792 * @param array the array to traverse for looking for the object, may be {@code null}
1793 * @param valueToFind the value to find
1794 * @param startIndex the start index to travers backwards from
1795 * @return the last index of the value within the array,
1796 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1797 */
1798 public static int lastIndexOf(final long[] array, final long valueToFind, int startIndex) {
1799 if (array == null) {
1800 return INDEX_NOT_FOUND;
1801 }
1802 if (startIndex < 0) {
1803 return INDEX_NOT_FOUND;
1804 } else if (startIndex >= array.length) {
1805 startIndex = array.length - 1;
1806 }
1807 for (int i = startIndex; i >= 0; i--) {
1808 if (valueToFind == array[i]) {
1809 return i;
1810 }
1811 }
1812 return INDEX_NOT_FOUND;
1813 }
1814
1815 /**
1816 * <p>Checks if the value is in the given array.</p>
1817 *
1818 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
1819 *
1820 * @param array the array to search through
1821 * @param valueToFind the value to find
1822 * @return {@code true} if the array contains the object
1823 */
1824 public static boolean contains(final long[] array, final long valueToFind) {
1825 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1826 }
1827
1828 // int IndexOf
1829 //-----------------------------------------------------------------------
1830 /**
1831 * <p>Finds the index of the given value in the array.</p>
1832 *
1833 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1834 *
1835 * @param array the array to search through for the object, may be {@code null}
1836 * @param valueToFind the value to find
1837 * @return the index of the value within the array,
1838 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1839 */
1840 public static int indexOf(final int[] array, final int valueToFind) {
1841 return indexOf(array, valueToFind, 0);
1842 }
1843
1844 /**
1845 * <p>Finds the index of the given value in the array starting at the given index.</p>
1846 *
1847 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1848 *
1849 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1850 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
1851 *
1852 * @param array the array to search through for the object, may be {@code null}
1853 * @param valueToFind the value to find
1854 * @param startIndex the index to start searching at
1855 * @return the index of the value within the array,
1856 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1857 */
1858 public static int indexOf(final int[] array, final int valueToFind, int startIndex) {
1859 if (array == null) {
1860 return INDEX_NOT_FOUND;
1861 }
1862 if (startIndex < 0) {
1863 startIndex = 0;
1864 }
1865 for (int i = startIndex; i < array.length; i++) {
1866 if (valueToFind == array[i]) {
1867 return i;
1868 }
1869 }
1870 return INDEX_NOT_FOUND;
1871 }
1872
1873 /**
1874 * <p>Finds the last index of the given value within the array.</p>
1875 *
1876 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1877 *
1878 * @param array the array to travers backwords looking for the object, may be {@code null}
1879 * @param valueToFind the object to find
1880 * @return the last index of the value within the array,
1881 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1882 */
1883 public static int lastIndexOf(final int[] array, final int valueToFind) {
1884 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1885 }
1886
1887 /**
1888 * <p>Finds the last index of the given value in the array starting at the given index.</p>
1889 *
1890 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1891 *
1892 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
1893 * array length will search from the end of the array.</p>
1894 *
1895 * @param array the array to traverse for looking for the object, may be {@code null}
1896 * @param valueToFind the value to find
1897 * @param startIndex the start index to travers backwards from
1898 * @return the last index of the value within the array,
1899 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1900 */
1901 public static int lastIndexOf(final int[] array, final int valueToFind, int startIndex) {
1902 if (array == null) {
1903 return INDEX_NOT_FOUND;
1904 }
1905 if (startIndex < 0) {
1906 return INDEX_NOT_FOUND;
1907 } else if (startIndex >= array.length) {
1908 startIndex = array.length - 1;
1909 }
1910 for (int i = startIndex; i >= 0; i--) {
1911 if (valueToFind == array[i]) {
1912 return i;
1913 }
1914 }
1915 return INDEX_NOT_FOUND;
1916 }
1917
1918 /**
1919 * <p>Checks if the value is in the given array.</p>
1920 *
1921 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
1922 *
1923 * @param array the array to search through
1924 * @param valueToFind the value to find
1925 * @return {@code true} if the array contains the object
1926 */
1927 public static boolean contains(final int[] array, final int valueToFind) {
1928 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
1929 }
1930
1931 // short IndexOf
1932 //-----------------------------------------------------------------------
1933 /**
1934 * <p>Finds the index of the given value in the array.</p>
1935 *
1936 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1937 *
1938 * @param array the array to search through for the object, may be {@code null}
1939 * @param valueToFind the value to find
1940 * @return the index of the value within the array,
1941 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1942 */
1943 public static int indexOf(final short[] array, final short valueToFind) {
1944 return indexOf(array, valueToFind, 0);
1945 }
1946
1947 /**
1948 * <p>Finds the index of the given value in the array starting at the given index.</p>
1949 *
1950 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1951 *
1952 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1953 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
1954 *
1955 * @param array the array to search through for the object, may be {@code null}
1956 * @param valueToFind the value to find
1957 * @param startIndex the index to start searching at
1958 * @return the index of the value within the array,
1959 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1960 */
1961 public static int indexOf(final short[] array, final short valueToFind, int startIndex) {
1962 if (array == null) {
1963 return INDEX_NOT_FOUND;
1964 }
1965 if (startIndex < 0) {
1966 startIndex = 0;
1967 }
1968 for (int i = startIndex; i < array.length; i++) {
1969 if (valueToFind == array[i]) {
1970 return i;
1971 }
1972 }
1973 return INDEX_NOT_FOUND;
1974 }
1975
1976 /**
1977 * <p>Finds the last index of the given value within the array.</p>
1978 *
1979 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1980 *
1981 * @param array the array to travers backwords looking for the object, may be {@code null}
1982 * @param valueToFind the object to find
1983 * @return the last index of the value within the array,
1984 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
1985 */
1986 public static int lastIndexOf(final short[] array, final short valueToFind) {
1987 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
1988 }
1989
1990 /**
1991 * <p>Finds the last index of the given value in the array starting at the given index.</p>
1992 *
1993 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
1994 *
1995 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
1996 * array length will search from the end of the array.</p>
1997 *
1998 * @param array the array to traverse for looking for the object, may be {@code null}
1999 * @param valueToFind the value to find
2000 * @param startIndex the start index to travers backwards from
2001 * @return the last index of the value within the array,
2002 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2003 */
2004 public static int lastIndexOf(final short[] array, final short valueToFind, int startIndex) {
2005 if (array == null) {
2006 return INDEX_NOT_FOUND;
2007 }
2008 if (startIndex < 0) {
2009 return INDEX_NOT_FOUND;
2010 } else if (startIndex >= array.length) {
2011 startIndex = array.length - 1;
2012 }
2013 for (int i = startIndex; i >= 0; i--) {
2014 if (valueToFind == array[i]) {
2015 return i;
2016 }
2017 }
2018 return INDEX_NOT_FOUND;
2019 }
2020
2021 /**
2022 * <p>Checks if the value is in the given array.</p>
2023 *
2024 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2025 *
2026 * @param array the array to search through
2027 * @param valueToFind the value to find
2028 * @return {@code true} if the array contains the object
2029 */
2030 public static boolean contains(final short[] array, final short valueToFind) {
2031 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2032 }
2033
2034 // char IndexOf
2035 //-----------------------------------------------------------------------
2036 /**
2037 * <p>Finds the index of the given value in the array.</p>
2038 *
2039 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2040 *
2041 * @param array the array to search through for the object, may be {@code null}
2042 * @param valueToFind the value to find
2043 * @return the index of the value within the array,
2044 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2045 * @since 2.1
2046 */
2047 public static int indexOf(final char[] array, final char valueToFind) {
2048 return indexOf(array, valueToFind, 0);
2049 }
2050
2051 /**
2052 * <p>Finds the index of the given value in the array starting at the given index.</p>
2053 *
2054 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2055 *
2056 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2057 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2058 *
2059 * @param array the array to search through for the object, may be {@code null}
2060 * @param valueToFind the value to find
2061 * @param startIndex the index to start searching at
2062 * @return the index of the value within the array,
2063 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2064 * @since 2.1
2065 */
2066 public static int indexOf(final char[] array, final char valueToFind, int startIndex) {
2067 if (array == null) {
2068 return INDEX_NOT_FOUND;
2069 }
2070 if (startIndex < 0) {
2071 startIndex = 0;
2072 }
2073 for (int i = startIndex; i < array.length; i++) {
2074 if (valueToFind == array[i]) {
2075 return i;
2076 }
2077 }
2078 return INDEX_NOT_FOUND;
2079 }
2080
2081 /**
2082 * <p>Finds the last index of the given value within the array.</p>
2083 *
2084 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2085 *
2086 * @param array the array to travers backwords looking for the object, may be {@code null}
2087 * @param valueToFind the object to find
2088 * @return the last index of the value within the array,
2089 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2090 * @since 2.1
2091 */
2092 public static int lastIndexOf(final char[] array, final char valueToFind) {
2093 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2094 }
2095
2096 /**
2097 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2098 *
2099 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2100 *
2101 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2102 * array length will search from the end of the array.</p>
2103 *
2104 * @param array the array to traverse for looking for the object, may be {@code null}
2105 * @param valueToFind the value to find
2106 * @param startIndex the start index to travers backwards from
2107 * @return the last index of the value within the array,
2108 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2109 * @since 2.1
2110 */
2111 public static int lastIndexOf(final char[] array, final char valueToFind, int startIndex) {
2112 if (array == null) {
2113 return INDEX_NOT_FOUND;
2114 }
2115 if (startIndex < 0) {
2116 return INDEX_NOT_FOUND;
2117 } else if (startIndex >= array.length) {
2118 startIndex = array.length - 1;
2119 }
2120 for (int i = startIndex; i >= 0; i--) {
2121 if (valueToFind == array[i]) {
2122 return i;
2123 }
2124 }
2125 return INDEX_NOT_FOUND;
2126 }
2127
2128 /**
2129 * <p>Checks if the value is in the given array.</p>
2130 *
2131 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2132 *
2133 * @param array the array to search through
2134 * @param valueToFind the value to find
2135 * @return {@code true} if the array contains the object
2136 * @since 2.1
2137 */
2138 public static boolean contains(final char[] array, final char valueToFind) {
2139 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2140 }
2141
2142 // byte IndexOf
2143 //-----------------------------------------------------------------------
2144 /**
2145 * <p>Finds the index of the given value in the array.</p>
2146 *
2147 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2148 *
2149 * @param array the array to search through for the object, may be {@code null}
2150 * @param valueToFind the value to find
2151 * @return the index of the value within the array,
2152 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2153 */
2154 public static int indexOf(final byte[] array, final byte valueToFind) {
2155 return indexOf(array, valueToFind, 0);
2156 }
2157
2158 /**
2159 * <p>Finds the index of the given value in the array starting at the given index.</p>
2160 *
2161 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2162 *
2163 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2164 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2165 *
2166 * @param array the array to search through for the object, may be {@code null}
2167 * @param valueToFind the value to find
2168 * @param startIndex the index to start searching at
2169 * @return the index of the value within the array,
2170 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2171 */
2172 public static int indexOf(final byte[] array, final byte valueToFind, int startIndex) {
2173 if (array == null) {
2174 return INDEX_NOT_FOUND;
2175 }
2176 if (startIndex < 0) {
2177 startIndex = 0;
2178 }
2179 for (int i = startIndex; i < array.length; i++) {
2180 if (valueToFind == array[i]) {
2181 return i;
2182 }
2183 }
2184 return INDEX_NOT_FOUND;
2185 }
2186
2187 /**
2188 * <p>Finds the last index of the given value within the array.</p>
2189 *
2190 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2191 *
2192 * @param array the array to travers backwords looking for the object, may be {@code null}
2193 * @param valueToFind the object to find
2194 * @return the last index of the value within the array,
2195 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2196 */
2197 public static int lastIndexOf(final byte[] array, final byte valueToFind) {
2198 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2199 }
2200
2201 /**
2202 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2203 *
2204 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2205 *
2206 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2207 * array length will search from the end of the array.</p>
2208 *
2209 * @param array the array to traverse for looking for the object, may be {@code null}
2210 * @param valueToFind the value to find
2211 * @param startIndex the start index to travers backwards from
2212 * @return the last index of the value within the array,
2213 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2214 */
2215 public static int lastIndexOf(final byte[] array, final byte valueToFind, int startIndex) {
2216 if (array == null) {
2217 return INDEX_NOT_FOUND;
2218 }
2219 if (startIndex < 0) {
2220 return INDEX_NOT_FOUND;
2221 } else if (startIndex >= array.length) {
2222 startIndex = array.length - 1;
2223 }
2224 for (int i = startIndex; i >= 0; i--) {
2225 if (valueToFind == array[i]) {
2226 return i;
2227 }
2228 }
2229 return INDEX_NOT_FOUND;
2230 }
2231
2232 /**
2233 * <p>Checks if the value is in the given array.</p>
2234 *
2235 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2236 *
2237 * @param array the array to search through
2238 * @param valueToFind the value to find
2239 * @return {@code true} if the array contains the object
2240 */
2241 public static boolean contains(final byte[] array, final byte valueToFind) {
2242 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2243 }
2244
2245 // double IndexOf
2246 //-----------------------------------------------------------------------
2247 /**
2248 * <p>Finds the index of the given value in the array.</p>
2249 *
2250 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2251 *
2252 * @param array the array to search through for the object, may be {@code null}
2253 * @param valueToFind the value to find
2254 * @return the index of the value within the array,
2255 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2256 */
2257 public static int indexOf(final double[] array, final double valueToFind) {
2258 return indexOf(array, valueToFind, 0);
2259 }
2260
2261 /**
2262 * <p>Finds the index of the given value within a given tolerance in the array.
2263 * This method will return the index of the first value which falls between the region
2264 * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2265 *
2266 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2267 *
2268 * @param array the array to search through for the object, may be {@code null}
2269 * @param valueToFind the value to find
2270 * @param tolerance tolerance of the search
2271 * @return the index of the value within the array,
2272 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2273 */
2274 public static int indexOf(final double[] array, final double valueToFind, final double tolerance) {
2275 return indexOf(array, valueToFind, 0, tolerance);
2276 }
2277
2278 /**
2279 * <p>Finds the index of the given value in the array starting at the given index.</p>
2280 *
2281 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2282 *
2283 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2284 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2285 *
2286 * @param array the array to search through for the object, may be {@code null}
2287 * @param valueToFind the value to find
2288 * @param startIndex the index to start searching at
2289 * @return the index of the value within the array,
2290 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2291 */
2292 public static int indexOf(final double[] array, final double valueToFind, int startIndex) {
2293 if (ArrayUtils.isEmpty(array)) {
2294 return INDEX_NOT_FOUND;
2295 }
2296 if (startIndex < 0) {
2297 startIndex = 0;
2298 }
2299 for (int i = startIndex; i < array.length; i++) {
2300 if (valueToFind == array[i]) {
2301 return i;
2302 }
2303 }
2304 return INDEX_NOT_FOUND;
2305 }
2306
2307 /**
2308 * <p>Finds the index of the given value in the array starting at the given index.
2309 * This method will return the index of the first value which falls between the region
2310 * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2311 *
2312 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) 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 {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2316 *
2317 * @param array the array to search through for the object, may be {@code null}
2318 * @param valueToFind the value to find
2319 * @param startIndex the index to start searching at
2320 * @param tolerance tolerance of the search
2321 * @return the index of the value within the array,
2322 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2323 */
2324 public static int indexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
2325 if (ArrayUtils.isEmpty(array)) {
2326 return INDEX_NOT_FOUND;
2327 }
2328 if (startIndex < 0) {
2329 startIndex = 0;
2330 }
2331 final double min = valueToFind - tolerance;
2332 final double max = valueToFind + tolerance;
2333 for (int i = startIndex; i < array.length; i++) {
2334 if (array[i] >= min && array[i] <= max) {
2335 return i;
2336 }
2337 }
2338 return INDEX_NOT_FOUND;
2339 }
2340
2341 /**
2342 * <p>Finds the last index of the given value within the array.</p>
2343 *
2344 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2345 *
2346 * @param array the array to travers backwords looking for the object, may be {@code null}
2347 * @param valueToFind the object to find
2348 * @return the last index of the value within the array,
2349 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2350 */
2351 public static int lastIndexOf(final double[] array, final double valueToFind) {
2352 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2353 }
2354
2355 /**
2356 * <p>Finds the last index of the given value within a given tolerance in the array.
2357 * This method will return the index of the last value which falls between the region
2358 * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2359 *
2360 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2361 *
2362 * @param array the array to search through for the object, may be {@code null}
2363 * @param valueToFind the value to find
2364 * @param tolerance tolerance of the search
2365 * @return the index of the value within the array,
2366 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2367 */
2368 public static int lastIndexOf(final double[] array, final double valueToFind, final double tolerance) {
2369 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
2370 }
2371
2372 /**
2373 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2374 *
2375 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2376 *
2377 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2378 * array length will search from the end of the array.</p>
2379 *
2380 * @param array the array to traverse for looking for the object, may be {@code null}
2381 * @param valueToFind the value to find
2382 * @param startIndex the start index to travers backwards from
2383 * @return the last index of the value within the array,
2384 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2385 */
2386 public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex) {
2387 if (ArrayUtils.isEmpty(array)) {
2388 return INDEX_NOT_FOUND;
2389 }
2390 if (startIndex < 0) {
2391 return INDEX_NOT_FOUND;
2392 } else if (startIndex >= array.length) {
2393 startIndex = array.length - 1;
2394 }
2395 for (int i = startIndex; i >= 0; i--) {
2396 if (valueToFind == array[i]) {
2397 return i;
2398 }
2399 }
2400 return INDEX_NOT_FOUND;
2401 }
2402
2403 /**
2404 * <p>Finds the last index of the given value in the array starting at the given index.
2405 * This method will return the index of the last value which falls between the region
2406 * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
2407 *
2408 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2409 *
2410 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2411 * array length will search from the end of the array.</p>
2412 *
2413 * @param array the array to traverse for looking for the object, may be {@code null}
2414 * @param valueToFind the value to find
2415 * @param startIndex the start index to travers backwards from
2416 * @param tolerance search for value within plus/minus this amount
2417 * @return the last index of the value within the array,
2418 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2419 */
2420 public static int lastIndexOf(final double[] array, final double valueToFind, int startIndex, final double tolerance) {
2421 if (ArrayUtils.isEmpty(array)) {
2422 return INDEX_NOT_FOUND;
2423 }
2424 if (startIndex < 0) {
2425 return INDEX_NOT_FOUND;
2426 } else if (startIndex >= array.length) {
2427 startIndex = array.length - 1;
2428 }
2429 final double min = valueToFind - tolerance;
2430 final double max = valueToFind + tolerance;
2431 for (int i = startIndex; i >= 0; i--) {
2432 if (array[i] >= min && array[i] <= max) {
2433 return i;
2434 }
2435 }
2436 return INDEX_NOT_FOUND;
2437 }
2438
2439 /**
2440 * <p>Checks if the value is in the given array.</p>
2441 *
2442 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2443 *
2444 * @param array the array to search through
2445 * @param valueToFind the value to find
2446 * @return {@code true} if the array contains the object
2447 */
2448 public static boolean contains(final double[] array, final double valueToFind) {
2449 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2450 }
2451
2452 /**
2453 * <p>Checks if a value falling within the given tolerance is in the
2454 * given array. If the array contains a value within the inclusive range
2455 * defined by (value - tolerance) to (value + tolerance).</p>
2456 *
2457 * <p>The method returns {@code false} if a {@code null} array
2458 * is passed in.</p>
2459 *
2460 * @param array the array to search
2461 * @param valueToFind the value to find
2462 * @param tolerance the array contains the tolerance of the search
2463 * @return true if value falling within tolerance is in array
2464 */
2465 public static boolean contains(final double[] array, final double valueToFind, final double tolerance) {
2466 return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
2467 }
2468
2469 // float IndexOf
2470 //-----------------------------------------------------------------------
2471 /**
2472 * <p>Finds the index of the given value in the array.</p>
2473 *
2474 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2475 *
2476 * @param array the array to search through for the object, may be {@code null}
2477 * @param valueToFind the value to find
2478 * @return the index of the value within the array,
2479 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2480 */
2481 public static int indexOf(final float[] array, final float valueToFind) {
2482 return indexOf(array, valueToFind, 0);
2483 }
2484
2485 /**
2486 * <p>Finds the index of the given value in the array starting at the given index.</p>
2487 *
2488 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2489 *
2490 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2491 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2492 *
2493 * @param array the array to search through for the object, may be {@code null}
2494 * @param valueToFind the value to find
2495 * @param startIndex the index to start searching at
2496 * @return the index of the value within the array,
2497 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2498 */
2499 public static int indexOf(final float[] array, final float valueToFind, int startIndex) {
2500 if (ArrayUtils.isEmpty(array)) {
2501 return INDEX_NOT_FOUND;
2502 }
2503 if (startIndex < 0) {
2504 startIndex = 0;
2505 }
2506 for (int i = startIndex; i < array.length; i++) {
2507 if (valueToFind == array[i]) {
2508 return i;
2509 }
2510 }
2511 return INDEX_NOT_FOUND;
2512 }
2513
2514 /**
2515 * <p>Finds the last index of the given value within the array.</p>
2516 *
2517 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2518 *
2519 * @param array the array to travers backwords looking for the object, may be {@code null}
2520 * @param valueToFind the object to find
2521 * @return the last index of the value within the array,
2522 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2523 */
2524 public static int lastIndexOf(final float[] array, final float valueToFind) {
2525 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2526 }
2527
2528 /**
2529 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2530 *
2531 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2532 *
2533 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
2534 * array length will search from the end of the array.</p>
2535 *
2536 * @param array the array to traverse for looking for the object, may be {@code null}
2537 * @param valueToFind the value to find
2538 * @param startIndex the start index to travers backwards from
2539 * @return the last index of the value within the array,
2540 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2541 */
2542 public static int lastIndexOf(final float[] array, final float valueToFind, int startIndex) {
2543 if (ArrayUtils.isEmpty(array)) {
2544 return INDEX_NOT_FOUND;
2545 }
2546 if (startIndex < 0) {
2547 return INDEX_NOT_FOUND;
2548 } else if (startIndex >= array.length) {
2549 startIndex = array.length - 1;
2550 }
2551 for (int i = startIndex; i >= 0; i--) {
2552 if (valueToFind == array[i]) {
2553 return i;
2554 }
2555 }
2556 return INDEX_NOT_FOUND;
2557 }
2558
2559 /**
2560 * <p>Checks if the value is in the given array.</p>
2561 *
2562 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2563 *
2564 * @param array the array to search through
2565 * @param valueToFind the value to find
2566 * @return {@code true} if the array contains the object
2567 */
2568 public static boolean contains(final float[] array, final float valueToFind) {
2569 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2570 }
2571
2572 // boolean IndexOf
2573 //-----------------------------------------------------------------------
2574 /**
2575 * <p>Finds the index of the given value in the array.</p>
2576 *
2577 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2578 *
2579 * @param array the array to search through for the object, may be {@code null}
2580 * @param valueToFind the value to find
2581 * @return the index of the value within the array,
2582 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2583 */
2584 public static int indexOf(final boolean[] array, final boolean valueToFind) {
2585 return indexOf(array, valueToFind, 0);
2586 }
2587
2588 /**
2589 * <p>Finds the index of the given value in the array starting at the given index.</p>
2590 *
2591 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2592 *
2593 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
2594 * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
2595 *
2596 * @param array the array to search through for the object, may be {@code null}
2597 * @param valueToFind the value to find
2598 * @param startIndex the index to start searching at
2599 * @return the index of the value within the array,
2600 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
2601 * array input
2602 */
2603 public static int indexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
2604 if (ArrayUtils.isEmpty(array)) {
2605 return INDEX_NOT_FOUND;
2606 }
2607 if (startIndex < 0) {
2608 startIndex = 0;
2609 }
2610 for (int i = startIndex; i < array.length; i++) {
2611 if (valueToFind == array[i]) {
2612 return i;
2613 }
2614 }
2615 return INDEX_NOT_FOUND;
2616 }
2617
2618 /**
2619 * <p>Finds the last index of the given value within the array.</p>
2620 *
2621 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) if
2622 * {@code null} array input.</p>
2623 *
2624 * @param array the array to travers backwords looking for the object, may be {@code null}
2625 * @param valueToFind the object to find
2626 * @return the last index of the value within the array,
2627 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2628 */
2629 public static int lastIndexOf(final boolean[] array, final boolean valueToFind) {
2630 return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
2631 }
2632
2633 /**
2634 * <p>Finds the last index of the given value in the array starting at the given index.</p>
2635 *
2636 * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
2637 *
2638 * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
2639 * the array length will search from the end of the array.</p>
2640 *
2641 * @param array the array to traverse for looking for the object, may be {@code null}
2642 * @param valueToFind the value to find
2643 * @param startIndex the start index to travers backwards from
2644 * @return the last index of the value within the array,
2645 * {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
2646 */
2647 public static int lastIndexOf(final boolean[] array, final boolean valueToFind, int startIndex) {
2648 if (ArrayUtils.isEmpty(array)) {
2649 return INDEX_NOT_FOUND;
2650 }
2651 if (startIndex < 0) {
2652 return INDEX_NOT_FOUND;
2653 } else if (startIndex >= array.length) {
2654 startIndex = array.length - 1;
2655 }
2656 for (int i = startIndex; i >= 0; i--) {
2657 if (valueToFind == array[i]) {
2658 return i;
2659 }
2660 }
2661 return INDEX_NOT_FOUND;
2662 }
2663
2664 /**
2665 * <p>Checks if the value is in the given array.</p>
2666 *
2667 * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
2668 *
2669 * @param array the array to search through
2670 * @param valueToFind the value to find
2671 * @return {@code true} if the array contains the object
2672 */
2673 public static boolean contains(final boolean[] array, final boolean valueToFind) {
2674 return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
2675 }
2676
2677 // Primitive/Object array converters
2678 // ----------------------------------------------------------------------
2679
2680 // Character array converters
2681 // ----------------------------------------------------------------------
2682 /**
2683 * <p>Converts an array of object Characters to primitives.</p>
2684 *
2685 * <p>This method returns {@code null} for a {@code null} input array.</p>
2686 *
2687 * @param array a {@code Character} array, may be {@code null}
2688 * @return a {@code char} array, {@code null} if null array input
2689 * @throws NullPointerException if array content is {@code null}
2690 */
2691 public static char[] toPrimitive(final Character[] array) {
2692 if (array == null) {
2693 return null;
2694 } else if (array.length == 0) {
2695 return EMPTY_CHAR_ARRAY;
2696 }
2697 final char[] result = new char[array.length];
2698 for (int i = 0; i < array.length; i++) {
2699 result[i] = array[i].charValue();
2700 }
2701 return result;
2702 }
2703
2704 /**
2705 * <p>Converts an array of object Character to primitives handling {@code null}.</p>
2706 *
2707 * <p>This method returns {@code null} for a {@code null} input array.</p>
2708 *
2709 * @param array a {@code Character} array, may be {@code null}
2710 * @param valueForNull the value to insert if {@code null} found
2711 * @return a {@code char} array, {@code null} if null array input
2712 */
2713 public static char[] toPrimitive(final Character[] array, final char valueForNull) {
2714 if (array == null) {
2715 return null;
2716 } else if (array.length == 0) {
2717 return EMPTY_CHAR_ARRAY;
2718 }
2719 final char[] result = new char[array.length];
2720 for (int i = 0; i < array.length; i++) {
2721 final Character b = array[i];
2722 result[i] = (b == null ? valueForNull : b.charValue());
2723 }
2724 return result;
2725 }
2726
2727 /**
2728 * <p>Converts an array of primitive chars to objects.</p>
2729 *
2730 * <p>This method returns {@code null} for a {@code null} input array.</p>
2731 *
2732 * @param array a {@code char} array
2733 * @return a {@code Character} array, {@code null} if null array input
2734 */
2735 public static Character[] toObject(final char[] array) {
2736 if (array == null) {
2737 return null;
2738 } else if (array.length == 0) {
2739 return EMPTY_CHARACTER_OBJECT_ARRAY;
2740 }
2741 final Character[] result = new Character[array.length];
2742 for (int i = 0; i < array.length; i++) {
2743 result[i] = Character.valueOf(array[i]);
2744 }
2745 return result;
2746 }
2747
2748 // Long array converters
2749 // ----------------------------------------------------------------------
2750 /**
2751 * <p>Converts an array of object Longs to primitives.</p>
2752 *
2753 * <p>This method returns {@code null} for a {@code null} input array.</p>
2754 *
2755 * @param array a {@code Long} array, may be {@code null}
2756 * @return a {@code long} array, {@code null} if null array input
2757 * @throws NullPointerException if array content is {@code null}
2758 */
2759 public static long[] toPrimitive(final Long[] array) {
2760 if (array == null) {
2761 return null;
2762 } else if (array.length == 0) {
2763 return EMPTY_LONG_ARRAY;
2764 }
2765 final long[] result = new long[array.length];
2766 for (int i = 0; i < array.length; i++) {
2767 result[i] = array[i].longValue();
2768 }
2769 return result;
2770 }
2771
2772 /**
2773 * <p>Converts an array of object Long to primitives handling {@code null}.</p>
2774 *
2775 * <p>This method returns {@code null} for a {@code null} input array.</p>
2776 *
2777 * @param array a {@code Long} array, may be {@code null}
2778 * @param valueForNull the value to insert if {@code null} found
2779 * @return a {@code long} array, {@code null} if null array input
2780 */
2781 public static long[] toPrimitive(final Long[] array, final long valueForNull) {
2782 if (array == null) {
2783 return null;
2784 } else if (array.length == 0) {
2785 return EMPTY_LONG_ARRAY;
2786 }
2787 final long[] result = new long[array.length];
2788 for (int i = 0; i < array.length; i++) {
2789 final Long b = array[i];
2790 result[i] = (b == null ? valueForNull : b.longValue());
2791 }
2792 return result;
2793 }
2794
2795 /**
2796 * <p>Converts an array of primitive longs to objects.</p>
2797 *
2798 * <p>This method returns {@code null} for a {@code null} input array.</p>
2799 *
2800 * @param array a {@code long} array
2801 * @return a {@code Long} array, {@code null} if null array input
2802 */
2803 public static Long[] toObject(final long[] array) {
2804 if (array == null) {
2805 return null;
2806 } else if (array.length == 0) {
2807 return EMPTY_LONG_OBJECT_ARRAY;
2808 }
2809 final Long[] result = new Long[array.length];
2810 for (int i = 0; i < array.length; i++) {
2811 result[i] = Long.valueOf(array[i]);
2812 }
2813 return result;
2814 }
2815
2816 // Int array converters
2817 // ----------------------------------------------------------------------
2818 /**
2819 * <p>Converts an array of object Integers to primitives.</p>
2820 *
2821 * <p>This method returns {@code null} for a {@code null} input array.</p>
2822 *
2823 * @param array a {@code Integer} array, may be {@code null}
2824 * @return an {@code int} array, {@code null} if null array input
2825 * @throws NullPointerException if array content is {@code null}
2826 */
2827 public static int[] toPrimitive(final Integer[] array) {
2828 if (array == null) {
2829 return null;
2830 } else if (array.length == 0) {
2831 return EMPTY_INT_ARRAY;
2832 }
2833 final int[] result = new int[array.length];
2834 for (int i = 0; i < array.length; i++) {
2835 result[i] = array[i].intValue();
2836 }
2837 return result;
2838 }
2839
2840 /**
2841 * <p>Converts an array of object Integer to primitives handling {@code null}.</p>
2842 *
2843 * <p>This method returns {@code null} for a {@code null} input array.</p>
2844 *
2845 * @param array a {@code Integer} array, may be {@code null}
2846 * @param valueForNull the value to insert if {@code null} found
2847 * @return an {@code int} array, {@code null} if null array input
2848 */
2849 public static int[] toPrimitive(final Integer[] array, final int valueForNull) {
2850 if (array == null) {
2851 return null;
2852 } else if (array.length == 0) {
2853 return EMPTY_INT_ARRAY;
2854 }
2855 final int[] result = new int[array.length];
2856 for (int i = 0; i < array.length; i++) {
2857 final Integer b = array[i];
2858 result[i] = (b == null ? valueForNull : b.intValue());
2859 }
2860 return result;
2861 }
2862
2863 /**
2864 * <p>Converts an array of primitive ints to objects.</p>
2865 *
2866 * <p>This method returns {@code null} for a {@code null} input array.</p>
2867 *
2868 * @param array an {@code int} array
2869 * @return an {@code Integer} array, {@code null} if null array input
2870 */
2871 public static Integer[] toObject(final int[] array) {
2872 if (array == null) {
2873 return null;
2874 } else if (array.length == 0) {
2875 return EMPTY_INTEGER_OBJECT_ARRAY;
2876 }
2877 final Integer[] result = new Integer[array.length];
2878 for (int i = 0; i < array.length; i++) {
2879 result[i] = Integer.valueOf(array[i]);
2880 }
2881 return result;
2882 }
2883
2884 // Short array converters
2885 // ----------------------------------------------------------------------
2886 /**
2887 * <p>Converts an array of object Shorts to primitives.</p>
2888 *
2889 * <p>This method returns {@code null} for a {@code null} input array.</p>
2890 *
2891 * @param array a {@code Short} array, may be {@code null}
2892 * @return a {@code byte} array, {@code null} if null array input
2893 * @throws NullPointerException if array content is {@code null}
2894 */
2895 public static short[] toPrimitive(final Short[] array) {
2896 if (array == null) {
2897 return null;
2898 } else if (array.length == 0) {
2899 return EMPTY_SHORT_ARRAY;
2900 }
2901 final short[] result = new short[array.length];
2902 for (int i = 0; i < array.length; i++) {
2903 result[i] = array[i].shortValue();
2904 }
2905 return result;
2906 }
2907
2908 /**
2909 * <p>Converts an array of object Short to primitives handling {@code null}.</p>
2910 *
2911 * <p>This method returns {@code null} for a {@code null} input array.</p>
2912 *
2913 * @param array a {@code Short} array, may be {@code null}
2914 * @param valueForNull the value to insert if {@code null} found
2915 * @return a {@code byte} array, {@code null} if null array input
2916 */
2917 public static short[] toPrimitive(final Short[] array, final short valueForNull) {
2918 if (array == null) {
2919 return null;
2920 } else if (array.length == 0) {
2921 return EMPTY_SHORT_ARRAY;
2922 }
2923 final short[] result = new short[array.length];
2924 for (int i = 0; i < array.length; i++) {
2925 final Short b = array[i];
2926 result[i] = (b == null ? valueForNull : b.shortValue());
2927 }
2928 return result;
2929 }
2930
2931 /**
2932 * <p>Converts an array of primitive shorts to objects.</p>
2933 *
2934 * <p>This method returns {@code null} for a {@code null} input array.</p>
2935 *
2936 * @param array a {@code short} array
2937 * @return a {@code Short} array, {@code null} if null array input
2938 */
2939 public static Short[] toObject(final short[] array) {
2940 if (array == null) {
2941 return null;
2942 } else if (array.length == 0) {
2943 return EMPTY_SHORT_OBJECT_ARRAY;
2944 }
2945 final Short[] result = new Short[array.length];
2946 for (int i = 0; i < array.length; i++) {
2947 result[i] = Short.valueOf(array[i]);
2948 }
2949 return result;
2950 }
2951
2952 // Byte array converters
2953 // ----------------------------------------------------------------------
2954 /**
2955 * <p>Converts an array of object Bytes to primitives.</p>
2956 *
2957 * <p>This method returns {@code null} for a {@code null} input array.</p>
2958 *
2959 * @param array a {@code Byte} array, may be {@code null}
2960 * @return a {@code byte} array, {@code null} if null array input
2961 * @throws NullPointerException if array content is {@code null}
2962 */
2963 public static byte[] toPrimitive(final Byte[] array) {
2964 if (array == null) {
2965 return null;
2966 } else if (array.length == 0) {
2967 return EMPTY_BYTE_ARRAY;
2968 }
2969 final byte[] result = new byte[array.length];
2970 for (int i = 0; i < array.length; i++) {
2971 result[i] = array[i].byteValue();
2972 }
2973 return result;
2974 }
2975
2976 /**
2977 * <p>Converts an array of object Bytes to primitives handling {@code null}.</p>
2978 *
2979 * <p>This method returns {@code null} for a {@code null} input array.</p>
2980 *
2981 * @param array a {@code Byte} array, may be {@code null}
2982 * @param valueForNull the value to insert if {@code null} found
2983 * @return a {@code byte} array, {@code null} if null array input
2984 */
2985 public static byte[] toPrimitive(final Byte[] array, final byte valueForNull) {
2986 if (array == null) {
2987 return null;
2988 } else if (array.length == 0) {
2989 return EMPTY_BYTE_ARRAY;
2990 }
2991 final byte[] result = new byte[array.length];
2992 for (int i = 0; i < array.length; i++) {
2993 final Byte b = array[i];
2994 result[i] = (b == null ? valueForNull : b.byteValue());
2995 }
2996 return result;
2997 }
2998
2999 /**
3000 * <p>Converts an array of primitive bytes to objects.</p>
3001 *
3002 * <p>This method returns {@code null} for a {@code null} input array.</p>
3003 *
3004 * @param array a {@code byte} array
3005 * @return a {@code Byte} array, {@code null} if null array input
3006 */
3007 public static Byte[] toObject(final byte[] array) {
3008 if (array == null) {
3009 return null;
3010 } else if (array.length == 0) {
3011 return EMPTY_BYTE_OBJECT_ARRAY;
3012 }
3013 final Byte[] result = new Byte[array.length];
3014 for (int i = 0; i < array.length; i++) {
3015 result[i] = Byte.valueOf(array[i]);
3016 }
3017 return result;
3018 }
3019
3020 // Double array converters
3021 // ----------------------------------------------------------------------
3022 /**
3023 * <p>Converts an array of object Doubles to primitives.</p>
3024 *
3025 * <p>This method returns {@code null} for a {@code null} input array.</p>
3026 *
3027 * @param array a {@code Double} array, may be {@code null}
3028 * @return a {@code double} array, {@code null} if null array input
3029 * @throws NullPointerException if array content is {@code null}
3030 */
3031 public static double[] toPrimitive(final Double[] array) {
3032 if (array == null) {
3033 return null;
3034 } else if (array.length == 0) {
3035 return EMPTY_DOUBLE_ARRAY;
3036 }
3037 final double[] result = new double[array.length];
3038 for (int i = 0; i < array.length; i++) {
3039 result[i] = array[i].doubleValue();
3040 }
3041 return result;
3042 }
3043
3044 /**
3045 * <p>Converts an array of object Doubles to primitives handling {@code null}.</p>
3046 *
3047 * <p>This method returns {@code null} for a {@code null} input array.</p>
3048 *
3049 * @param array a {@code Double} array, may be {@code null}
3050 * @param valueForNull the value to insert if {@code null} found
3051 * @return a {@code double} array, {@code null} if null array input
3052 */
3053 public static double[] toPrimitive(final Double[] array, final double valueForNull) {
3054 if (array == null) {
3055 return null;
3056 } else if (array.length == 0) {
3057 return EMPTY_DOUBLE_ARRAY;
3058 }
3059 final double[] result = new double[array.length];
3060 for (int i = 0; i < array.length; i++) {
3061 final Double b = array[i];
3062 result[i] = (b == null ? valueForNull : b.doubleValue());
3063 }
3064 return result;
3065 }
3066
3067 /**
3068 * <p>Converts an array of primitive doubles to objects.</p>
3069 *
3070 * <p>This method returns {@code null} for a {@code null} input array.</p>
3071 *
3072 * @param array a {@code double} array
3073 * @return a {@code Double} array, {@code null} if null array input
3074 */
3075 public static Double[] toObject(final double[] array) {
3076 if (array == null) {
3077 return null;
3078 } else if (array.length == 0) {
3079 return EMPTY_DOUBLE_OBJECT_ARRAY;
3080 }
3081 final Double[] result = new Double[array.length];
3082 for (int i = 0; i < array.length; i++) {
3083 result[i] = Double.valueOf(array[i]);
3084 }
3085 return result;
3086 }
3087
3088 // Float array converters
3089 // ----------------------------------------------------------------------
3090 /**
3091 * <p>Converts an array of object Floats to primitives.</p>
3092 *
3093 * <p>This method returns {@code null} for a {@code null} input array.</p>
3094 *
3095 * @param array a {@code Float} array, may be {@code null}
3096 * @return a {@code float} array, {@code null} if null array input
3097 * @throws NullPointerException if array content is {@code null}
3098 */
3099 public static float[] toPrimitive(final Float[] array) {
3100 if (array == null) {
3101 return null;
3102 } else if (array.length == 0) {
3103 return EMPTY_FLOAT_ARRAY;
3104 }
3105 final float[] result = new float[array.length];
3106 for (int i = 0; i < array.length; i++) {
3107 result[i] = array[i].floatValue();
3108 }
3109 return result;
3110 }
3111
3112 /**
3113 * <p>Converts an array of object Floats to primitives handling {@code null}.</p>
3114 *
3115 * <p>This method returns {@code null} for a {@code null} input array.</p>
3116 *
3117 * @param array a {@code Float} array, may be {@code null}
3118 * @param valueForNull the value to insert if {@code null} found
3119 * @return a {@code float} array, {@code null} if null array input
3120 */
3121 public static float[] toPrimitive(final Float[] array, final float valueForNull) {
3122 if (array == null) {
3123 return null;
3124 } else if (array.length == 0) {
3125 return EMPTY_FLOAT_ARRAY;
3126 }
3127 final float[] result = new float[array.length];
3128 for (int i = 0; i < array.length; i++) {
3129 final Float b = array[i];
3130 result[i] = (b == null ? valueForNull : b.floatValue());
3131 }
3132 return result;
3133 }
3134
3135 /**
3136 * <p>Converts an array of primitive floats to objects.</p>
3137 *
3138 * <p>This method returns {@code null} for a {@code null} input array.</p>
3139 *
3140 * @param array a {@code float} array
3141 * @return a {@code Float} array, {@code null} if null array input
3142 */
3143 public static Float[] toObject(final float[] array) {
3144 if (array == null) {
3145 return null;
3146 } else if (array.length == 0) {
3147 return EMPTY_FLOAT_OBJECT_ARRAY;
3148 }
3149 final Float[] result = new Float[array.length];
3150 for (int i = 0; i < array.length; i++) {
3151 result[i] = Float.valueOf(array[i]);
3152 }
3153 return result;
3154 }
3155
3156 // Boolean array converters
3157 // ----------------------------------------------------------------------
3158 /**
3159 * <p>Converts an array of object Booleans to primitives.</p>
3160 *
3161 * <p>This method returns {@code null} for a {@code null} input array.</p>
3162 *
3163 * @param array a {@code Boolean} array, may be {@code null}
3164 * @return a {@code boolean} array, {@code null} if null array input
3165 * @throws NullPointerException if array content is {@code null}
3166 */
3167 public static boolean[] toPrimitive(final Boolean[] array) {
3168 if (array == null) {
3169 return null;
3170 } else if (array.length == 0) {
3171 return EMPTY_BOOLEAN_ARRAY;
3172 }
3173 final boolean[] result = new boolean[array.length];
3174 for (int i = 0; i < array.length; i++) {
3175 result[i] = array[i].booleanValue();
3176 }
3177 return result;
3178 }
3179
3180 /**
3181 * <p>Converts an array of object Booleans to primitives handling {@code null}.</p>
3182 *
3183 * <p>This method returns {@code null} for a {@code null} input array.</p>
3184 *
3185 * @param array a {@code Boolean} array, may be {@code null}
3186 * @param valueForNull the value to insert if {@code null} found
3187 * @return a {@code boolean} array, {@code null} if null array input
3188 */
3189 public static boolean[] toPrimitive(final Boolean[] array, final boolean valueForNull) {
3190 if (array == null) {
3191 return null;
3192 } else if (array.length == 0) {
3193 return EMPTY_BOOLEAN_ARRAY;
3194 }
3195 final boolean[] result = new boolean[array.length];
3196 for (int i = 0; i < array.length; i++) {
3197 final Boolean b = array[i];
3198 result[i] = (b == null ? valueForNull : b.booleanValue());
3199 }
3200 return result;
3201 }
3202
3203 /**
3204 * <p>Converts an array of primitive booleans to objects.</p>
3205 *
3206 * <p>This method returns {@code null} for a {@code null} input array.</p>
3207 *
3208 * @param array a {@code boolean} array
3209 * @return a {@code Boolean} array, {@code null} if null array input
3210 */
3211 public static Boolean[] toObject(final boolean[] array) {
3212 if (array == null) {
3213 return null;
3214 } else if (array.length == 0) {
3215 return EMPTY_BOOLEAN_OBJECT_ARRAY;
3216 }
3217 final Boolean[] result = new Boolean[array.length];
3218 for (int i = 0; i < array.length; i++) {
3219 result[i] = (array[i] ? Boolean.TRUE : Boolean.FALSE);
3220 }
3221 return result;
3222 }
3223
3224 // ----------------------------------------------------------------------
3225 /**
3226 * <p>Checks if an array of Objects is empty or {@code null}.</p>
3227 *
3228 * @param array the array to test
3229 * @return {@code true} if the array is empty or {@code null}
3230 * @since 2.1
3231 */
3232 public static boolean isEmpty(final Object[] array) {
3233 return array == null || array.length == 0;
3234 }
3235
3236 /**
3237 * <p>Checks if an array of primitive longs is empty or {@code null}.</p>
3238 *
3239 * @param array the array to test
3240 * @return {@code true} if the array is empty or {@code null}
3241 * @since 2.1
3242 */
3243 public static boolean isEmpty(final long[] array) {
3244 return array == null || array.length == 0;
3245 }
3246
3247 /**
3248 * <p>Checks if an array of primitive ints is empty or {@code null}.</p>
3249 *
3250 * @param array the array to test
3251 * @return {@code true} if the array is empty or {@code null}
3252 * @since 2.1
3253 */
3254 public static boolean isEmpty(final int[] array) {
3255 return array == null || array.length == 0;
3256 }
3257
3258 /**
3259 * <p>Checks if an array of primitive shorts is empty or {@code null}.</p>
3260 *
3261 * @param array the array to test
3262 * @return {@code true} if the array is empty or {@code null}
3263 * @since 2.1
3264 */
3265 public static boolean isEmpty(final short[] array) {
3266 return array == null || array.length == 0;
3267 }
3268
3269 /**
3270 * <p>Checks if an array of primitive chars is empty or {@code null}.</p>
3271 *
3272 * @param array the array to test
3273 * @return {@code true} if the array is empty or {@code null}
3274 * @since 2.1
3275 */
3276 public static boolean isEmpty(final char[] array) {
3277 return array == null || array.length == 0;
3278 }
3279
3280 /**
3281 * <p>Checks if an array of primitive bytes is empty or {@code null}.</p>
3282 *
3283 * @param array the array to test
3284 * @return {@code true} if the array is empty or {@code null}
3285 * @since 2.1
3286 */
3287 public static boolean isEmpty(final byte[] array) {
3288 return array == null || array.length == 0;
3289 }
3290
3291 /**
3292 * <p>Checks if an array of primitive doubles is empty or {@code null}.</p>
3293 *
3294 * @param array the array to test
3295 * @return {@code true} if the array is empty or {@code null}
3296 * @since 2.1
3297 */
3298 public static boolean isEmpty(final double[] array) {
3299 return array == null || array.length == 0;
3300 }
3301
3302 /**
3303 * <p>Checks if an array of primitive floats is empty or {@code null}.</p>
3304 *
3305 * @param array the array to test
3306 * @return {@code true} if the array is empty or {@code null}
3307 * @since 2.1
3308 */
3309 public static boolean isEmpty(final float[] array) {
3310 return array == null || array.length == 0;
3311 }
3312
3313 /**
3314 * <p>Checks if an array of primitive booleans is empty or {@code null}.</p>
3315 *
3316 * @param array the array to test
3317 * @return {@code true} if the array is empty or {@code null}
3318 * @since 2.1
3319 */
3320 public static boolean isEmpty(final boolean[] array) {
3321 return array == null || array.length == 0;
3322 }
3323
3324 // ----------------------------------------------------------------------
3325 /**
3326 * <p>Checks if an array of Objects is not empty or not {@code null}.</p>
3327 *
3328 * @param <T> the component type of the array
3329 * @param array the array to test
3330 * @return {@code true} if the array is not empty or not {@code null}
3331 * @since 2.5
3332 */
3333 public static <T> boolean isNotEmpty(final T[] array) {
3334 return (array != null && array.length != 0);
3335 }
3336
3337 /**
3338 * <p>Checks if an array of primitive longs is not empty or not {@code null}.</p>
3339 *
3340 * @param array the array to test
3341 * @return {@code true} if the array is not empty or not {@code null}
3342 * @since 2.5
3343 */
3344 public static boolean isNotEmpty(final long[] array) {
3345 return (array != null && array.length != 0);
3346 }
3347
3348 /**
3349 * <p>Checks if an array of primitive ints is not empty or not {@code null}.</p>
3350 *
3351 * @param array the array to test
3352 * @return {@code true} if the array is not empty or not {@code null}
3353 * @since 2.5
3354 */
3355 public static boolean isNotEmpty(final int[] array) {
3356 return (array != null && array.length != 0);
3357 }
3358
3359 /**
3360 * <p>Checks if an array of primitive shorts is not empty or not {@code null}.</p>
3361 *
3362 * @param array the array to test
3363 * @return {@code true} if the array is not empty or not {@code null}
3364 * @since 2.5
3365 */
3366 public static boolean isNotEmpty(final short[] array) {
3367 return (array != null && array.length != 0);
3368 }
3369
3370 /**
3371 * <p>Checks if an array of primitive chars is not empty or not {@code null}.</p>
3372 *
3373 * @param array the array to test
3374 * @return {@code true} if the array is not empty or not {@code null}
3375 * @since 2.5
3376 */
3377 public static boolean isNotEmpty(final char[] array) {
3378 return (array != null && array.length != 0);
3379 }
3380
3381 /**
3382 * <p>Checks if an array of primitive bytes is not empty or not {@code null}.</p>
3383 *
3384 * @param array the array to test
3385 * @return {@code true} if the array is not empty or not {@code null}
3386 * @since 2.5
3387 */
3388 public static boolean isNotEmpty(final byte[] array) {
3389 return (array != null && array.length != 0);
3390 }
3391
3392 /**
3393 * <p>Checks if an array of primitive doubles is not empty or not {@code null}.</p>
3394 *
3395 * @param array the array to test
3396 * @return {@code true} if the array is not empty or not {@code null}
3397 * @since 2.5
3398 */
3399 public static boolean isNotEmpty(final double[] array) {
3400 return (array != null && array.length != 0);
3401 }
3402
3403 /**
3404 * <p>Checks if an array of primitive floats is not empty or not {@code null}.</p>
3405 *
3406 * @param array the array to test
3407 * @return {@code true} if the array is not empty or not {@code null}
3408 * @since 2.5
3409 */
3410 public static boolean isNotEmpty(final float[] array) {
3411 return (array != null && array.length != 0);
3412 }
3413
3414 /**
3415 * <p>Checks if an array of primitive booleans is not empty or not {@code null}.</p>
3416 *
3417 * @param array the array to test
3418 * @return {@code true} if the array is not empty or not {@code null}
3419 * @since 2.5
3420 */
3421 public static boolean isNotEmpty(final boolean[] array) {
3422 return (array != null && array.length != 0);
3423 }
3424
3425 /**
3426 * <p>Adds all the elements of the given arrays into a new array.</p>
3427 * <p>The new array contains all of the element of {@code array1} followed
3428 * by all of the elements {@code array2}. When an array is returned, it is always
3429 * a new array.</p>
3430 *
3431 * <pre>
3432 * ArrayUtils.addAll(null, null) = null
3433 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3434 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3435 * ArrayUtils.addAll([], []) = []
3436 * ArrayUtils.addAll([null], [null]) = [null, null]
3437 * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
3438 * </pre>
3439 *
3440 * @param <T> the component type of the array
3441 * @param array1 the first array whose elements are added to the new array, may be {@code null}
3442 * @param array2 the second array whose elements are added to the new array, may be {@code null}
3443 * @return The new array, {@code null} if both arrays are {@code null}.
3444 * The type of the new array is the type of the first array,
3445 * unless the first array is null, in which case the type is the same as the second array.
3446 * @since 2.1
3447 * @throws IllegalArgumentException if the array types are incompatible
3448 */
3449 public static <T> T[] addAll(final T[] array1, final T... array2) {
3450 if (array1 == null) {
3451 return clone(array2);
3452 } else if (array2 == null) {
3453 return clone(array1);
3454 }
3455 final Class<?> type1 = array1.getClass().getComponentType();
3456 @SuppressWarnings("unchecked") // OK, because array is of type T
3457 final
3458 T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
3459 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3460 try {
3461 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3462 } catch (final ArrayStoreException ase) {
3463 // Check if problem was due to incompatible types
3464 /*
3465 * We do this here, rather than before the copy because:
3466 * - it would be a wasted check most of the time
3467 * - safer, in case check turns out to be too strict
3468 */
3469 final Class<?> type2 = array2.getClass().getComponentType();
3470 if (!type1.isAssignableFrom(type2)){
3471 throw new IllegalArgumentException("Cannot store "+type2.getName()+" in an array of "
3472 +type1.getName(), ase);
3473 }
3474 throw ase; // No, so rethrow original
3475 }
3476 return joinedArray;
3477 }
3478
3479 /**
3480 * <p>Adds all the elements of the given arrays into a new array.</p>
3481 * <p>The new array contains all of the element of {@code array1} followed
3482 * by all of the elements {@code array2}. When an array is returned, it is always
3483 * a new array.</p>
3484 *
3485 * <pre>
3486 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3487 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3488 * ArrayUtils.addAll([], []) = []
3489 * </pre>
3490 *
3491 * @param array1 the first array whose elements are added to the new array.
3492 * @param array2 the second array whose elements are added to the new array.
3493 * @return The new boolean[] array.
3494 * @since 2.1
3495 */
3496 public static boolean[] addAll(final boolean[] array1, final boolean... array2) {
3497 if (array1 == null) {
3498 return clone(array2);
3499 } else if (array2 == null) {
3500 return clone(array1);
3501 }
3502 final boolean[] joinedArray = new boolean[array1.length + array2.length];
3503 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3504 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3505 return joinedArray;
3506 }
3507
3508 /**
3509 * <p>Adds all the elements of the given arrays into a new array.</p>
3510 * <p>The new array contains all of the element of {@code array1} followed
3511 * by all of the elements {@code array2}. When an array is returned, it is always
3512 * a new array.</p>
3513 *
3514 * <pre>
3515 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3516 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3517 * ArrayUtils.addAll([], []) = []
3518 * </pre>
3519 *
3520 * @param array1 the first array whose elements are added to the new array.
3521 * @param array2 the second array whose elements are added to the new array.
3522 * @return The new char[] array.
3523 * @since 2.1
3524 */
3525 public static char[] addAll(final char[] array1, final char... array2) {
3526 if (array1 == null) {
3527 return clone(array2);
3528 } else if (array2 == null) {
3529 return clone(array1);
3530 }
3531 final char[] joinedArray = new char[array1.length + array2.length];
3532 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3533 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3534 return joinedArray;
3535 }
3536
3537 /**
3538 * <p>Adds all the elements of the given arrays into a new array.</p>
3539 * <p>The new array contains all of the element of {@code array1} followed
3540 * by all of the elements {@code array2}. When an array is returned, it is always
3541 * a new array.</p>
3542 *
3543 * <pre>
3544 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3545 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3546 * ArrayUtils.addAll([], []) = []
3547 * </pre>
3548 *
3549 * @param array1 the first array whose elements are added to the new array.
3550 * @param array2 the second array whose elements are added to the new array.
3551 * @return The new byte[] array.
3552 * @since 2.1
3553 */
3554 public static byte[] addAll(final byte[] array1, final byte... array2) {
3555 if (array1 == null) {
3556 return clone(array2);
3557 } else if (array2 == null) {
3558 return clone(array1);
3559 }
3560 final byte[] joinedArray = new byte[array1.length + array2.length];
3561 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3562 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3563 return joinedArray;
3564 }
3565
3566 /**
3567 * <p>Adds all the elements of the given arrays into a new array.</p>
3568 * <p>The new array contains all of the element of {@code array1} followed
3569 * by all of the elements {@code array2}. When an array is returned, it is always
3570 * a new array.</p>
3571 *
3572 * <pre>
3573 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3574 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3575 * ArrayUtils.addAll([], []) = []
3576 * </pre>
3577 *
3578 * @param array1 the first array whose elements are added to the new array.
3579 * @param array2 the second array whose elements are added to the new array.
3580 * @return The new short[] array.
3581 * @since 2.1
3582 */
3583 public static short[] addAll(final short[] array1, final short... array2) {
3584 if (array1 == null) {
3585 return clone(array2);
3586 } else if (array2 == null) {
3587 return clone(array1);
3588 }
3589 final short[] joinedArray = new short[array1.length + array2.length];
3590 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3591 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3592 return joinedArray;
3593 }
3594
3595 /**
3596 * <p>Adds all the elements of the given arrays into a new array.</p>
3597 * <p>The new array contains all of the element of {@code array1} followed
3598 * by all of the elements {@code array2}. When an array is returned, it is always
3599 * a new array.</p>
3600 *
3601 * <pre>
3602 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3603 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3604 * ArrayUtils.addAll([], []) = []
3605 * </pre>
3606 *
3607 * @param array1 the first array whose elements are added to the new array.
3608 * @param array2 the second array whose elements are added to the new array.
3609 * @return The new int[] array.
3610 * @since 2.1
3611 */
3612 public static int[] addAll(final int[] array1, final int... array2) {
3613 if (array1 == null) {
3614 return clone(array2);
3615 } else if (array2 == null) {
3616 return clone(array1);
3617 }
3618 final int[] joinedArray = new int[array1.length + array2.length];
3619 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3620 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3621 return joinedArray;
3622 }
3623
3624 /**
3625 * <p>Adds all the elements of the given arrays into a new array.</p>
3626 * <p>The new array contains all of the element of {@code array1} followed
3627 * by all of the elements {@code array2}. When an array is returned, it is always
3628 * a new array.</p>
3629 *
3630 * <pre>
3631 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3632 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3633 * ArrayUtils.addAll([], []) = []
3634 * </pre>
3635 *
3636 * @param array1 the first array whose elements are added to the new array.
3637 * @param array2 the second array whose elements are added to the new array.
3638 * @return The new long[] array.
3639 * @since 2.1
3640 */
3641 public static long[] addAll(final long[] array1, final long... array2) {
3642 if (array1 == null) {
3643 return clone(array2);
3644 } else if (array2 == null) {
3645 return clone(array1);
3646 }
3647 final long[] joinedArray = new long[array1.length + array2.length];
3648 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3649 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3650 return joinedArray;
3651 }
3652
3653 /**
3654 * <p>Adds all the elements of the given arrays into a new array.</p>
3655 * <p>The new array contains all of the element of {@code array1} followed
3656 * by all of the elements {@code array2}. When an array is returned, it is always
3657 * a new array.</p>
3658 *
3659 * <pre>
3660 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3661 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3662 * ArrayUtils.addAll([], []) = []
3663 * </pre>
3664 *
3665 * @param array1 the first array whose elements are added to the new array.
3666 * @param array2 the second array whose elements are added to the new array.
3667 * @return The new float[] array.
3668 * @since 2.1
3669 */
3670 public static float[] addAll(final float[] array1, final float... array2) {
3671 if (array1 == null) {
3672 return clone(array2);
3673 } else if (array2 == null) {
3674 return clone(array1);
3675 }
3676 final float[] joinedArray = new float[array1.length + array2.length];
3677 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3678 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3679 return joinedArray;
3680 }
3681
3682 /**
3683 * <p>Adds all the elements of the given arrays into a new array.</p>
3684 * <p>The new array contains all of the element of {@code array1} followed
3685 * by all of the elements {@code array2}. When an array is returned, it is always
3686 * a new array.</p>
3687 *
3688 * <pre>
3689 * ArrayUtils.addAll(array1, null) = cloned copy of array1
3690 * ArrayUtils.addAll(null, array2) = cloned copy of array2
3691 * ArrayUtils.addAll([], []) = []
3692 * </pre>
3693 *
3694 * @param array1 the first array whose elements are added to the new array.
3695 * @param array2 the second array whose elements are added to the new array.
3696 * @return The new double[] array.
3697 * @since 2.1
3698 */
3699 public static double[] addAll(final double[] array1, final double... array2) {
3700 if (array1 == null) {
3701 return clone(array2);
3702 } else if (array2 == null) {
3703 return clone(array1);
3704 }
3705 final double[] joinedArray = new double[array1.length + array2.length];
3706 System.arraycopy(array1, 0, joinedArray, 0, array1.length);
3707 System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
3708 return joinedArray;
3709 }
3710
3711 /**
3712 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3713 *
3714 * <p>The new array contains the same elements of the input
3715 * array plus the given element in the last position. The component type of
3716 * the new array is the same as that of the input array.</p>
3717 *
3718 * <p>If the input array is {@code null}, a new one element array is returned
3719 * whose component type is the same as the element, unless the element itself is null,
3720 * in which case the return type is Object[]</p>
3721 *
3722 * <pre>
3723 * ArrayUtils.add(null, null) = [null]
3724 * ArrayUtils.add(null, "a") = ["a"]
3725 * ArrayUtils.add(["a"], null) = ["a", null]
3726 * ArrayUtils.add(["a"], "b") = ["a", "b"]
3727 * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
3728 * </pre>
3729 *
3730 * @param <T> the component type of the array
3731 * @param array the array to "add" the element to, may be {@code null}
3732 * @param element the object to add, may be {@code null}
3733 * @return A new array containing the existing elements plus the new element
3734 * The returned array type will be that of the input array (unless null),
3735 * in which case it will have the same type as the element.
3736 * If both are null, an IllegalArgumentException is thrown
3737 * @since 2.1
3738 * @throws IllegalArgumentException if both arguments are null
3739 */
3740 public static <T> T[] add(final T[] array, final T element) {
3741 Class<?> type;
3742 if (array != null){
3743 type = array.getClass();
3744 } else if (element != null) {
3745 type = element.getClass();
3746 } else {
3747 throw new IllegalArgumentException("Arguments cannot both be null");
3748 }
3749 @SuppressWarnings("unchecked") // type must be T
3750 final
3751 T[] newArray = (T[]) copyArrayGrow1(array, type);
3752 newArray[newArray.length - 1] = element;
3753 return newArray;
3754 }
3755
3756 /**
3757 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3758 *
3759 * <p>The new array contains the same elements of the input
3760 * array plus the given element in the last position. The component type of
3761 * the new array is the same as that of the input array.</p>
3762 *
3763 * <p>If the input array is {@code null}, a new one element array is returned
3764 * whose component type is the same as the element.</p>
3765 *
3766 * <pre>
3767 * ArrayUtils.add(null, true) = [true]
3768 * ArrayUtils.add([true], false) = [true, false]
3769 * ArrayUtils.add([true, false], true) = [true, false, true]
3770 * </pre>
3771 *
3772 * @param array the array to copy and add the element to, may be {@code null}
3773 * @param element the object to add at the last index of the new array
3774 * @return A new array containing the existing elements plus the new element
3775 * @since 2.1
3776 */
3777 public static boolean[] add(final boolean[] array, final boolean element) {
3778 final boolean[] newArray = (boolean[])copyArrayGrow1(array, Boolean.TYPE);
3779 newArray[newArray.length - 1] = element;
3780 return newArray;
3781 }
3782
3783 /**
3784 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3785 *
3786 * <p>The new array contains the same elements of the input
3787 * array plus the given element in the last position. The component type of
3788 * the new array is the same as that of the input array.</p>
3789 *
3790 * <p>If the input array is {@code null}, a new one element array is returned
3791 * whose component type is the same as the element.</p>
3792 *
3793 * <pre>
3794 * ArrayUtils.add(null, 0) = [0]
3795 * ArrayUtils.add([1], 0) = [1, 0]
3796 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3797 * </pre>
3798 *
3799 * @param array the array to copy and add the element to, may be {@code null}
3800 * @param element the object to add at the last index of the new array
3801 * @return A new array containing the existing elements plus the new element
3802 * @since 2.1
3803 */
3804 public static byte[] add(final byte[] array, final byte element) {
3805 final byte[] newArray = (byte[])copyArrayGrow1(array, Byte.TYPE);
3806 newArray[newArray.length - 1] = element;
3807 return newArray;
3808 }
3809
3810 /**
3811 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3812 *
3813 * <p>The new array contains the same elements of the input
3814 * array plus the given element in the last position. The component type of
3815 * the new array is the same as that of the input array.</p>
3816 *
3817 * <p>If the input array is {@code null}, a new one element array is returned
3818 * whose component type is the same as the element.</p>
3819 *
3820 * <pre>
3821 * ArrayUtils.add(null, '0') = ['0']
3822 * ArrayUtils.add(['1'], '0') = ['1', '0']
3823 * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
3824 * </pre>
3825 *
3826 * @param array the array to copy and add the element to, may be {@code null}
3827 * @param element the object to add at the last index of the new array
3828 * @return A new array containing the existing elements plus the new element
3829 * @since 2.1
3830 */
3831 public static char[] add(final char[] array, final char element) {
3832 final char[] newArray = (char[])copyArrayGrow1(array, Character.TYPE);
3833 newArray[newArray.length - 1] = element;
3834 return newArray;
3835 }
3836
3837 /**
3838 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3839 *
3840 * <p>The new array contains the same elements of the input
3841 * array plus the given element in the last position. The component type of
3842 * the new array is the same as that of the input array.</p>
3843 *
3844 * <p>If the input array is {@code null}, a new one element array is returned
3845 * whose component type is the same as the element.</p>
3846 *
3847 * <pre>
3848 * ArrayUtils.add(null, 0) = [0]
3849 * ArrayUtils.add([1], 0) = [1, 0]
3850 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3851 * </pre>
3852 *
3853 * @param array the array to copy and add the element to, may be {@code null}
3854 * @param element the object to add at the last index of the new array
3855 * @return A new array containing the existing elements plus the new element
3856 * @since 2.1
3857 */
3858 public static double[] add(final double[] array, final double element) {
3859 final double[] newArray = (double[])copyArrayGrow1(array, Double.TYPE);
3860 newArray[newArray.length - 1] = element;
3861 return newArray;
3862 }
3863
3864 /**
3865 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3866 *
3867 * <p>The new array contains the same elements of the input
3868 * array plus the given element in the last position. The component type of
3869 * the new array is the same as that of the input array.</p>
3870 *
3871 * <p>If the input array is {@code null}, a new one element array is returned
3872 * whose component type is the same as the element.</p>
3873 *
3874 * <pre>
3875 * ArrayUtils.add(null, 0) = [0]
3876 * ArrayUtils.add([1], 0) = [1, 0]
3877 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3878 * </pre>
3879 *
3880 * @param array the array to copy and add the element to, may be {@code null}
3881 * @param element the object to add at the last index of the new array
3882 * @return A new array containing the existing elements plus the new element
3883 * @since 2.1
3884 */
3885 public static float[] add(final float[] array, final float element) {
3886 final float[] newArray = (float[])copyArrayGrow1(array, Float.TYPE);
3887 newArray[newArray.length - 1] = element;
3888 return newArray;
3889 }
3890
3891 /**
3892 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3893 *
3894 * <p>The new array contains the same elements of the input
3895 * array plus the given element in the last position. The component type of
3896 * the new array is the same as that of the input array.</p>
3897 *
3898 * <p>If the input array is {@code null}, a new one element array is returned
3899 * whose component type is the same as the element.</p>
3900 *
3901 * <pre>
3902 * ArrayUtils.add(null, 0) = [0]
3903 * ArrayUtils.add([1], 0) = [1, 0]
3904 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3905 * </pre>
3906 *
3907 * @param array the array to copy and add the element to, may be {@code null}
3908 * @param element the object to add at the last index of the new array
3909 * @return A new array containing the existing elements plus the new element
3910 * @since 2.1
3911 */
3912 public static int[] add(final int[] array, final int element) {
3913 final int[] newArray = (int[])copyArrayGrow1(array, Integer.TYPE);
3914 newArray[newArray.length - 1] = element;
3915 return newArray;
3916 }
3917
3918 /**
3919 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3920 *
3921 * <p>The new array contains the same elements of the input
3922 * array plus the given element in the last position. The component type of
3923 * the new array is the same as that of the input array.</p>
3924 *
3925 * <p>If the input array is {@code null}, a new one element array is returned
3926 * whose component type is the same as the element.</p>
3927 *
3928 * <pre>
3929 * ArrayUtils.add(null, 0) = [0]
3930 * ArrayUtils.add([1], 0) = [1, 0]
3931 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3932 * </pre>
3933 *
3934 * @param array the array to copy and add the element to, may be {@code null}
3935 * @param element the object to add at the last index of the new array
3936 * @return A new array containing the existing elements plus the new element
3937 * @since 2.1
3938 */
3939 public static long[] add(final long[] array, final long element) {
3940 final long[] newArray = (long[])copyArrayGrow1(array, Long.TYPE);
3941 newArray[newArray.length - 1] = element;
3942 return newArray;
3943 }
3944
3945 /**
3946 * <p>Copies the given array and adds the given element at the end of the new array.</p>
3947 *
3948 * <p>The new array contains the same elements of the input
3949 * array plus the given element in the last position. The component type of
3950 * the new array is the same as that of the input array.</p>
3951 *
3952 * <p>If the input array is {@code null}, a new one element array is returned
3953 * whose component type is the same as the element.</p>
3954 *
3955 * <pre>
3956 * ArrayUtils.add(null, 0) = [0]
3957 * ArrayUtils.add([1], 0) = [1, 0]
3958 * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
3959 * </pre>
3960 *
3961 * @param array the array to copy and add the element to, may be {@code null}
3962 * @param element the object to add at the last index of the new array
3963 * @return A new array containing the existing elements plus the new element
3964 * @since 2.1
3965 */
3966 public static short[] add(final short[] array, final short element) {
3967 final short[] newArray = (short[])copyArrayGrow1(array, Short.TYPE);
3968 newArray[newArray.length - 1] = element;
3969 return newArray;
3970 }
3971
3972 /**
3973 * Returns a copy of the given array of size 1 greater than the argument.
3974 * The last value of the array is left to the default value.
3975 *
3976 * @param array The array to copy, must not be {@code null}.
3977 * @param newArrayComponentType If {@code array} is {@code null}, create a
3978 * size 1 array of this type.
3979 * @return A new copy of the array of size 1 greater than the input.
3980 */
3981 private static Object copyArrayGrow1(final Object array, final Class<?> newArrayComponentType) {
3982 if (array != null) {
3983 final int arrayLength = Array.getLength(array);
3984 final Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
3985 System.arraycopy(array, 0, newArray, 0, arrayLength);
3986 return newArray;
3987 }
3988 return Array.newInstance(newArrayComponentType, 1);
3989 }
3990
3991 /**
3992 * <p>Inserts the specified element at the specified position in the array.
3993 * Shifts the element currently at that position (if any) and any subsequent
3994 * elements to the right (adds one to their indices).</p>
3995 *
3996 * <p>This method returns a new array with the same elements of the input
3997 * array plus the given element on the specified position. The component
3998 * type of the returned array is always the same as that of the input
3999 * array.</p>
4000 *
4001 * <p>If the input array is {@code null}, a new one element array is returned
4002 * whose component type is the same as the element.</p>
4003 *
4004 * <pre>
4005 * ArrayUtils.add(null, 0, null) = [null]
4006 * ArrayUtils.add(null, 0, "a") = ["a"]
4007 * ArrayUtils.add(["a"], 1, null) = ["a", null]
4008 * ArrayUtils.add(["a"], 1, "b") = ["a", "b"]
4009 * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
4010 * </pre>
4011 *
4012 * @param <T> the component type of the array
4013 * @param array the array to add the element to, may be {@code null}
4014 * @param index the position of the new object
4015 * @param element the object to add
4016 * @return A new array containing the existing elements and the new element
4017 * @throws IndexOutOfBoundsException if the index is out of range
4018 * (index < 0 || index > array.length).
4019 * @throws IllegalArgumentException if both array and element are null
4020 */
4021 public static <T> T[] add(final T[] array, final int index, final T element) {
4022 Class<?> clss = null;
4023 if (array != null) {
4024 clss = array.getClass().getComponentType();
4025 } else if (element != null) {
4026 clss = element.getClass();
4027 } else {
4028 throw new IllegalArgumentException("Array and element cannot both be null");
4029 }
4030 @SuppressWarnings("unchecked") // the add method creates an array of type clss, which is type T
4031 final T[] newArray = (T[]) add(array, index, element, clss);
4032 return newArray;
4033 }
4034
4035 /**
4036 * <p>Inserts the specified element at the specified position in the array.
4037 * Shifts the element currently at that position (if any) and any subsequent
4038 * elements to the right (adds one to their indices).</p>
4039 *
4040 * <p>This method returns a new array with the same elements of the input
4041 * array plus the given element on the specified position. The component
4042 * type of the returned array is always the same as that of the input
4043 * array.</p>
4044 *
4045 * <p>If the input array is {@code null}, a new one element array is returned
4046 * whose component type is the same as the element.</p>
4047 *
4048 * <pre>
4049 * ArrayUtils.add(null, 0, true) = [true]
4050 * ArrayUtils.add([true], 0, false) = [false, true]
4051 * ArrayUtils.add([false], 1, true) = [false, true]
4052 * ArrayUtils.add([true, false], 1, true) = [true, true, false]
4053 * </pre>
4054 *
4055 * @param array the array to add the element to, may be {@code null}
4056 * @param index the position of the new object
4057 * @param element the object to add
4058 * @return A new array containing the existing elements and the new element
4059 * @throws IndexOutOfBoundsException if the index is out of range
4060 * (index < 0 || index > array.length).
4061 */
4062 public static boolean[] add(final boolean[] array, final int index, final boolean element) {
4063 return (boolean[]) add(array, index, Boolean.valueOf(element), Boolean.TYPE);
4064 }
4065
4066 /**
4067 * <p>Inserts the specified element at the specified position in the array.
4068 * Shifts the element currently at that position (if any) and any subsequent
4069 * elements to the right (adds one to their indices).</p>
4070 *
4071 * <p>This method returns a new array with the same elements of the input
4072 * array plus the given element on the specified position. The component
4073 * type of the returned array is always the same as that of the input
4074 * array.</p>
4075 *
4076 * <p>If the input array is {@code null}, a new one element array is returned
4077 * whose component type is the same as the element.</p>
4078 *
4079 * <pre>
4080 * ArrayUtils.add(null, 0, 'a') = ['a']
4081 * ArrayUtils.add(['a'], 0, 'b') = ['b', 'a']
4082 * ArrayUtils.add(['a', 'b'], 0, 'c') = ['c', 'a', 'b']
4083 * ArrayUtils.add(['a', 'b'], 1, 'k') = ['a', 'k', 'b']
4084 * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
4085 * </pre>
4086 *
4087 * @param array the array to add the element to, may be {@code null}
4088 * @param index the position of the new object
4089 * @param element the object to add
4090 * @return A new array containing the existing elements and the new element
4091 * @throws IndexOutOfBoundsException if the index is out of range
4092 * (index < 0 || index > array.length).
4093 */
4094 public static char[] add(final char[] array, final int index, final char element) {
4095 return (char[]) add(array, index, Character.valueOf(element), Character.TYPE);
4096 }
4097
4098 /**
4099 * <p>Inserts the specified element at the specified position in the array.
4100 * Shifts the element currently at that position (if any) and any subsequent
4101 * elements to the right (adds one to their indices).</p>
4102 *
4103 * <p>This method returns a new array with the same elements of the input
4104 * array plus the given element on the specified position. The component
4105 * type of the returned array is always the same as that of the input
4106 * array.</p>
4107 *
4108 * <p>If the input array is {@code null}, a new one element array is returned
4109 * whose component type is the same as the element.</p>
4110 *
4111 * <pre>
4112 * ArrayUtils.add([1], 0, 2) = [2, 1]
4113 * ArrayUtils.add([2, 6], 2, 3) = [2, 6, 3]
4114 * ArrayUtils.add([2, 6], 0, 1) = [1, 2, 6]
4115 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
4116 * </pre>
4117 *
4118 * @param array the array to add the element to, may be {@code null}
4119 * @param index the position of the new object
4120 * @param element the object to add
4121 * @return A new array containing the existing elements and the new element
4122 * @throws IndexOutOfBoundsException if the index is out of range
4123 * (index < 0 || index > array.length).
4124 */
4125 public static byte[] add(final byte[] array, final int index, final byte element) {
4126 return (byte[]) add(array, index, Byte.valueOf(element), Byte.TYPE);
4127 }
4128
4129 /**
4130 * <p>Inserts the specified element at the specified position in the array.
4131 * Shifts the element currently at that position (if any) and any subsequent
4132 * elements to the right (adds one to their indices).</p>
4133 *
4134 * <p>This method returns a new array with the same elements of the input
4135 * array plus the given element on the specified position. The component
4136 * type of the returned array is always the same as that of the input
4137 * array.</p>
4138 *
4139 * <p>If the input array is {@code null}, a new one element array is returned
4140 * whose component type is the same as the element.</p>
4141 *
4142 * <pre>
4143 * ArrayUtils.add([1], 0, 2) = [2, 1]
4144 * ArrayUtils.add([2, 6], 2, 10) = [2, 6, 10]
4145 * ArrayUtils.add([2, 6], 0, -4) = [-4, 2, 6]
4146 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
4147 * </pre>
4148 *
4149 * @param array the array to add the element to, may be {@code null}
4150 * @param index the position of the new object
4151 * @param element the object to add
4152 * @return A new array containing the existing elements and the new element
4153 * @throws IndexOutOfBoundsException if the index is out of range
4154 * (index < 0 || index > array.length).
4155 */
4156 public static short[] add(final short[] array, final int index, final short element) {
4157 return (short[]) add(array, index, Short.valueOf(element), Short.TYPE);
4158 }
4159
4160 /**
4161 * <p>Inserts the specified element at the specified position in the array.
4162 * Shifts the element currently at that position (if any) and any subsequent
4163 * elements to the right (adds one to their indices).</p>
4164 *
4165 * <p>This method returns a new array with the same elements of the input
4166 * array plus the given element on the specified position. The component
4167 * type of the returned array is always the same as that of the input
4168 * array.</p>
4169 *
4170 * <p>If the input array is {@code null}, a new one element array is returned
4171 * whose component type is the same as the element.</p>
4172 *
4173 * <pre>
4174 * ArrayUtils.add([1], 0, 2) = [2, 1]
4175 * ArrayUtils.add([2, 6], 2, 10) = [2, 6, 10]
4176 * ArrayUtils.add([2, 6], 0, -4) = [-4, 2, 6]
4177 * ArrayUtils.add([2, 6, 3], 2, 1) = [2, 6, 1, 3]
4178 * </pre>
4179 *
4180 * @param array the array to add the element to, may be {@code null}
4181 * @param index the position of the new object
4182 * @param element the object to add
4183 * @return A new array containing the existing elements and the new element
4184 * @throws IndexOutOfBoundsException if the index is out of range
4185 * (index < 0 || index > array.length).
4186 */
4187 public static int[] add(final int[] array, final int index, final int element) {
4188 return (int[]) add(array, index, Integer.valueOf(element), Integer.TYPE);
4189 }
4190
4191 /**
4192 * <p>Inserts the specified element at the specified position in the array.
4193 * Shifts the element currently at that position (if any) and any subsequent
4194 * elements to the right (adds one to their indices).</p>
4195 *
4196 * <p>This method returns a new array with the same elements of the input
4197 * array plus the given element on the specified position. The component
4198 * type of the returned array is always the same as that of the input
4199 * array.</p>
4200 *
4201 * <p>If the input array is {@code null}, a new one element array is returned
4202 * whose component type is the same as the element.</p>
4203 *
4204 * <pre>
4205 * ArrayUtils.add([1L], 0, 2L) = [2L, 1L]
4206 * ArrayUtils.add([2L, 6L], 2, 10L) = [2L, 6L, 10L]
4207 * ArrayUtils.add([2L, 6L], 0, -4L) = [-4L, 2L, 6L]
4208 * ArrayUtils.add([2L, 6L, 3L], 2, 1L) = [2L, 6L, 1L, 3L]
4209 * </pre>
4210 *
4211 * @param array the array to add the element to, may be {@code null}
4212 * @param index the position of the new object
4213 * @param element the object to add
4214 * @return A new array containing the existing elements and the new element
4215 * @throws IndexOutOfBoundsException if the index is out of range
4216 * (index < 0 || index > array.length).
4217 */
4218 public static long[] add(final long[] array, final int index, final long element) {
4219 return (long[]) add(array, index, Long.valueOf(element), Long.TYPE);
4220 }
4221
4222 /**
4223 * <p>Inserts the specified element at the specified position in the array.
4224 * Shifts the element currently at that position (if any) and any subsequent
4225 * elements to the right (adds one to their indices).</p>
4226 *
4227 * <p>This method returns a new array with the same elements of the input
4228 * array plus the given element on the specified position. The component
4229 * type of the returned array is always the same as that of the input
4230 * array.</p>
4231 *
4232 * <p>If the input array is {@code null}, a new one element array is returned
4233 * whose component type is the same as the element.</p>
4234 *
4235 * <pre>
4236 * ArrayUtils.add([1.1f], 0, 2.2f) = [2.2f, 1.1f]
4237 * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f) = [2.3f, 6.4f, 10.5f]
4238 * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f) = [-4.8f, 2.6f, 6.7f]
4239 * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f) = [2.9f, 6.0f, 1.0f, 0.3f]
4240 * </pre>
4241 *
4242 * @param array the array to add the element to, may be {@code null}
4243 * @param index the position of the new object
4244 * @param element the object to add
4245 * @return A new array containing the existing elements and the new element
4246 * @throws IndexOutOfBoundsException if the index is out of range
4247 * (index < 0 || index > array.length).
4248 */
4249 public static float[] add(final float[] array, final int index, final float element) {
4250 return (float[]) add(array, index, Float.valueOf(element), Float.TYPE);
4251 }
4252
4253 /**
4254 * <p>Inserts the specified element at the specified position in the array.
4255 * Shifts the element currently at that position (if any) and any subsequent
4256 * elements to the right (adds one to their indices).</p>
4257 *
4258 * <p>This method returns a new array with the same elements of the input
4259 * array plus the given element on the specified position. The component
4260 * type of the returned array is always the same as that of the input
4261 * array.</p>
4262 *
4263 * <p>If the input array is {@code null}, a new one element array is returned
4264 * whose component type is the same as the element.</p>
4265 *
4266 * <pre>
4267 * ArrayUtils.add([1.1], 0, 2.2) = [2.2, 1.1]
4268 * ArrayUtils.add([2.3, 6.4], 2, 10.5) = [2.3, 6.4, 10.5]
4269 * ArrayUtils.add([2.6, 6.7], 0, -4.8) = [-4.8, 2.6, 6.7]
4270 * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0) = [2.9, 6.0, 1.0, 0.3]
4271 * </pre>
4272 *
4273 * @param array the array to add the element to, may be {@code null}
4274 * @param index the position of the new object
4275 * @param element the object to add
4276 * @return A new array containing the existing elements and the new element
4277 * @throws IndexOutOfBoundsException if the index is out of range
4278 * (index < 0 || index > array.length).
4279 */
4280 public static double[] add(final double[] array, final int index, final double element) {
4281 return (double[]) add(array, index, Double.valueOf(element), Double.TYPE);
4282 }
4283
4284 /**
4285 * Underlying implementation of add(array, index, element) methods.
4286 * The last parameter is the class, which may not equal element.getClass
4287 * for primitives.
4288 *
4289 * @param array the array to add the element to, may be {@code null}
4290 * @param index the position of the new object
4291 * @param element the object to add
4292 * @param clss the type of the element being added
4293 * @return A new array containing the existing elements and the new element
4294 */
4295 private static Object add(final Object array, final int index, final Object element, final Class<?> clss) {
4296 if (array == null) {
4297 if (index != 0) {
4298 throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
4299 }
4300 final Object joinedArray = Array.newInstance(clss, 1);
4301 Array.set(joinedArray, 0, element);
4302 return joinedArray;
4303 }
4304 final int length = Array.getLength(array);
4305 if (index > length || index < 0) {
4306 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
4307 }
4308 final Object result = Array.newInstance(clss, length + 1);
4309 System.arraycopy(array, 0, result, 0, index);
4310 Array.set(result, index, element);
4311 if (index < length) {
4312 System.arraycopy(array, index, result, index + 1, length - index);
4313 }
4314 return result;
4315 }
4316
4317 /**
4318 * <p>Removes the element at the specified position from the specified array.
4319 * All subsequent elements are shifted to the left (subtracts one from
4320 * their indices).</p>
4321 *
4322 * <p>This method returns a new array with the same elements of the input
4323 * array except the element on the specified position. The component
4324 * type of the returned array is always the same as that of the input
4325 * array.</p>
4326 *
4327 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4328 * will be thrown, because in that case no valid index can be specified.</p>
4329 *
4330 * <pre>
4331 * ArrayUtils.remove(["a"], 0) = []
4332 * ArrayUtils.remove(["a", "b"], 0) = ["b"]
4333 * ArrayUtils.remove(["a", "b"], 1) = ["a"]
4334 * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
4335 * </pre>
4336 *
4337 * @param <T> the component type of the array
4338 * @param array the array to remove the element from, may not be {@code null}
4339 * @param index the position of the element to be removed
4340 * @return A new array containing the existing elements except the element
4341 * at the specified position.
4342 * @throws IndexOutOfBoundsException if the index is out of range
4343 * (index < 0 || index >= array.length), or if the array is {@code null}.
4344 * @since 2.1
4345 */
4346 @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
4347 public static <T> T[] remove(final T[] array, final int index) {
4348 return (T[]) remove((Object) array, index);
4349 }
4350
4351 /**
4352 * <p>Removes the first occurrence of the specified element from the
4353 * specified array. All subsequent elements are shifted to the left
4354 * (subtracts one from their indices). If the array doesn't contains
4355 * such an element, no elements are removed from the array.</p>
4356 *
4357 * <p>This method returns a new array with the same elements of the input
4358 * array except the first occurrence of the specified element. The component
4359 * type of the returned array is always the same as that of the input
4360 * array.</p>
4361 *
4362 * <pre>
4363 * ArrayUtils.removeElement(null, "a") = null
4364 * ArrayUtils.removeElement([], "a") = []
4365 * ArrayUtils.removeElement(["a"], "b") = ["a"]
4366 * ArrayUtils.removeElement(["a", "b"], "a") = ["b"]
4367 * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
4368 * </pre>
4369 *
4370 * @param <T> the component type of the array
4371 * @param array the array to remove the element from, may be {@code null}
4372 * @param element the element to be removed
4373 * @return A new array containing the existing elements except the first
4374 * occurrence of the specified element.
4375 * @since 2.1
4376 */
4377 public static <T> T[] removeElement(final T[] array, final Object element) {
4378 final int index = indexOf(array, element);
4379 if (index == INDEX_NOT_FOUND) {
4380 return clone(array);
4381 }
4382 return remove(array, index);
4383 }
4384
4385 /**
4386 * <p>Removes the element at the specified position from the specified array.
4387 * All subsequent elements are shifted to the left (subtracts one from
4388 * their indices).</p>
4389 *
4390 * <p>This method returns a new array with the same elements of the input
4391 * array except the element on the specified position. The component
4392 * type of the returned array is always the same as that of the input
4393 * array.</p>
4394 *
4395 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4396 * will be thrown, because in that case no valid index can be specified.</p>
4397 *
4398 * <pre>
4399 * ArrayUtils.remove([true], 0) = []
4400 * ArrayUtils.remove([true, false], 0) = [false]
4401 * ArrayUtils.remove([true, false], 1) = [true]
4402 * ArrayUtils.remove([true, true, false], 1) = [true, false]
4403 * </pre>
4404 *
4405 * @param array the array to remove the element from, may not be {@code null}
4406 * @param index the position of the element to be removed
4407 * @return A new array containing the existing elements except the element
4408 * at the specified position.
4409 * @throws IndexOutOfBoundsException if the index is out of range
4410 * (index < 0 || index >= array.length), or if the array is {@code null}.
4411 * @since 2.1
4412 */
4413 public static boolean[] remove(final boolean[] array, final int index) {
4414 return (boolean[]) remove((Object) array, index);
4415 }
4416
4417 /**
4418 * <p>Removes the first occurrence of the specified element from the
4419 * specified array. All subsequent elements are shifted to the left
4420 * (subtracts one from their indices). If the array doesn't contains
4421 * such an element, no elements are removed from the array.</p>
4422 *
4423 * <p>This method returns a new array with the same elements of the input
4424 * array except the first occurrence of the specified element. The component
4425 * type of the returned array is always the same as that of the input
4426 * array.</p>
4427 *
4428 * <pre>
4429 * ArrayUtils.removeElement(null, true) = null
4430 * ArrayUtils.removeElement([], true) = []
4431 * ArrayUtils.removeElement([true], false) = [true]
4432 * ArrayUtils.removeElement([true, false], false) = [true]
4433 * ArrayUtils.removeElement([true, false, true], true) = [false, true]
4434 * </pre>
4435 *
4436 * @param array the array to remove the element from, may be {@code null}
4437 * @param element the element to be removed
4438 * @return A new array containing the existing elements except the first
4439 * occurrence of the specified element.
4440 * @since 2.1
4441 */
4442 public static boolean[] removeElement(final boolean[] array, final boolean element) {
4443 final int index = indexOf(array, element);
4444 if (index == INDEX_NOT_FOUND) {
4445 return clone(array);
4446 }
4447 return remove(array, index);
4448 }
4449
4450 /**
4451 * <p>Removes the element at the specified position from the specified array.
4452 * All subsequent elements are shifted to the left (subtracts one from
4453 * their indices).</p>
4454 *
4455 * <p>This method returns a new array with the same elements of the input
4456 * array except the element on the specified position. The component
4457 * type of the returned array is always the same as that of the input
4458 * array.</p>
4459 *
4460 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4461 * will be thrown, because in that case no valid index can be specified.</p>
4462 *
4463 * <pre>
4464 * ArrayUtils.remove([1], 0) = []
4465 * ArrayUtils.remove([1, 0], 0) = [0]
4466 * ArrayUtils.remove([1, 0], 1) = [1]
4467 * ArrayUtils.remove([1, 0, 1], 1) = [1, 1]
4468 * </pre>
4469 *
4470 * @param array the array to remove the element from, may not be {@code null}
4471 * @param index the position of the element to be removed
4472 * @return A new array containing the existing elements except the element
4473 * at the specified position.
4474 * @throws IndexOutOfBoundsException if the index is out of range
4475 * (index < 0 || index >= array.length), or if the array is {@code null}.
4476 * @since 2.1
4477 */
4478 public static byte[] remove(final byte[] array, final int index) {
4479 return (byte[]) remove((Object) array, index);
4480 }
4481
4482 /**
4483 * <p>Removes the first occurrence of the specified element from the
4484 * specified array. All subsequent elements are shifted to the left
4485 * (subtracts one from their indices). If the array doesn't contains
4486 * such an element, no elements are removed from the array.</p>
4487 *
4488 * <p>This method returns a new array with the same elements of the input
4489 * array except the first occurrence of the specified element. The component
4490 * type of the returned array is always the same as that of the input
4491 * array.</p>
4492 *
4493 * <pre>
4494 * ArrayUtils.removeElement(null, 1) = null
4495 * ArrayUtils.removeElement([], 1) = []
4496 * ArrayUtils.removeElement([1], 0) = [1]
4497 * ArrayUtils.removeElement([1, 0], 0) = [1]
4498 * ArrayUtils.removeElement([1, 0, 1], 1) = [0, 1]
4499 * </pre>
4500 *
4501 * @param array the array to remove the element from, may be {@code null}
4502 * @param element the element to be removed
4503 * @return A new array containing the existing elements except the first
4504 * occurrence of the specified element.
4505 * @since 2.1
4506 */
4507 public static byte[] removeElement(final byte[] array, final byte element) {
4508 final int index = indexOf(array, element);
4509 if (index == INDEX_NOT_FOUND) {
4510 return clone(array);
4511 }
4512 return remove(array, index);
4513 }
4514
4515 /**
4516 * <p>Removes the element at the specified position from the specified array.
4517 * All subsequent elements are shifted to the left (subtracts one from
4518 * their indices).</p>
4519 *
4520 * <p>This method returns a new array with the same elements of the input
4521 * array except the element on the specified position. The component
4522 * type of the returned array is always the same as that of the input
4523 * array.</p>
4524 *
4525 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4526 * will be thrown, because in that case no valid index can be specified.</p>
4527 *
4528 * <pre>
4529 * ArrayUtils.remove(['a'], 0) = []
4530 * ArrayUtils.remove(['a', 'b'], 0) = ['b']
4531 * ArrayUtils.remove(['a', 'b'], 1) = ['a']
4532 * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
4533 * </pre>
4534 *
4535 * @param array the array to remove the element from, may not be {@code null}
4536 * @param index the position of the element to be removed
4537 * @return A new array containing the existing elements except the element
4538 * at the specified position.
4539 * @throws IndexOutOfBoundsException if the index is out of range
4540 * (index < 0 || index >= array.length), or if the array is {@code null}.
4541 * @since 2.1
4542 */
4543 public static char[] remove(final char[] array, final int index) {
4544 return (char[]) remove((Object) array, index);
4545 }
4546
4547 /**
4548 * <p>Removes the first occurrence of the specified element from the
4549 * specified array. All subsequent elements are shifted to the left
4550 * (subtracts one from their indices). If the array doesn't contains
4551 * such an element, no elements are removed from the array.</p>
4552 *
4553 * <p>This method returns a new array with the same elements of the input
4554 * array except the first occurrence of the specified element. The component
4555 * type of the returned array is always the same as that of the input
4556 * array.</p>
4557 *
4558 * <pre>
4559 * ArrayUtils.removeElement(null, 'a') = null
4560 * ArrayUtils.removeElement([], 'a') = []
4561 * ArrayUtils.removeElement(['a'], 'b') = ['a']
4562 * ArrayUtils.removeElement(['a', 'b'], 'a') = ['b']
4563 * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
4564 * </pre>
4565 *
4566 * @param array the array to remove the element from, may be {@code null}
4567 * @param element the element to be removed
4568 * @return A new array containing the existing elements except the first
4569 * occurrence of the specified element.
4570 * @since 2.1
4571 */
4572 public static char[] removeElement(final char[] array, final char element) {
4573 final int index = indexOf(array, element);
4574 if (index == INDEX_NOT_FOUND) {
4575 return clone(array);
4576 }
4577 return remove(array, index);
4578 }
4579
4580 /**
4581 * <p>Removes the element at the specified position from the specified array.
4582 * All subsequent elements are shifted to the left (subtracts one from
4583 * their indices).</p>
4584 *
4585 * <p>This method returns a new array with the same elements of the input
4586 * array except the element on the specified position. The component
4587 * type of the returned array is always the same as that of the input
4588 * array.</p>
4589 *
4590 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4591 * will be thrown, because in that case no valid index can be specified.</p>
4592 *
4593 * <pre>
4594 * ArrayUtils.remove([1.1], 0) = []
4595 * ArrayUtils.remove([2.5, 6.0], 0) = [6.0]
4596 * ArrayUtils.remove([2.5, 6.0], 1) = [2.5]
4597 * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4598 * </pre>
4599 *
4600 * @param array the array to remove the element from, may not be {@code null}
4601 * @param index the position of the element to be removed
4602 * @return A new array containing the existing elements except the element
4603 * at the specified position.
4604 * @throws IndexOutOfBoundsException if the index is out of range
4605 * (index < 0 || index >= array.length), or if the array is {@code null}.
4606 * @since 2.1
4607 */
4608 public static double[] remove(final double[] array, final int index) {
4609 return (double[]) remove((Object) array, index);
4610 }
4611
4612 /**
4613 * <p>Removes the first occurrence of the specified element from the
4614 * specified array. All subsequent elements are shifted to the left
4615 * (subtracts one from their indices). If the array doesn't contains
4616 * such an element, no elements are removed from the array.</p>
4617 *
4618 * <p>This method returns a new array with the same elements of the input
4619 * array except the first occurrence of the specified element. The component
4620 * type of the returned array is always the same as that of the input
4621 * array.</p>
4622 *
4623 * <pre>
4624 * ArrayUtils.removeElement(null, 1.1) = null
4625 * ArrayUtils.removeElement([], 1.1) = []
4626 * ArrayUtils.removeElement([1.1], 1.2) = [1.1]
4627 * ArrayUtils.removeElement([1.1, 2.3], 1.1) = [2.3]
4628 * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
4629 * </pre>
4630 *
4631 * @param array the array to remove the element from, may be {@code null}
4632 * @param element the element to be removed
4633 * @return A new array containing the existing elements except the first
4634 * occurrence of the specified element.
4635 * @since 2.1
4636 */
4637 public static double[] removeElement(final double[] array, final double element) {
4638 final int index = indexOf(array, element);
4639 if (index == INDEX_NOT_FOUND) {
4640 return clone(array);
4641 }
4642 return remove(array, index);
4643 }
4644
4645 /**
4646 * <p>Removes the element at the specified position from the specified array.
4647 * All subsequent elements are shifted to the left (subtracts one from
4648 * their indices).</p>
4649 *
4650 * <p>This method returns a new array with the same elements of the input
4651 * array except the element on the specified position. The component
4652 * type of the returned array is always the same as that of the input
4653 * array.</p>
4654 *
4655 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4656 * will be thrown, because in that case no valid index can be specified.</p>
4657 *
4658 * <pre>
4659 * ArrayUtils.remove([1.1], 0) = []
4660 * ArrayUtils.remove([2.5, 6.0], 0) = [6.0]
4661 * ArrayUtils.remove([2.5, 6.0], 1) = [2.5]
4662 * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
4663 * </pre>
4664 *
4665 * @param array the array to remove the element from, may not be {@code null}
4666 * @param index the position of the element to be removed
4667 * @return A new array containing the existing elements except the element
4668 * at the specified position.
4669 * @throws IndexOutOfBoundsException if the index is out of range
4670 * (index < 0 || index >= array.length), or if the array is {@code null}.
4671 * @since 2.1
4672 */
4673 public static float[] remove(final float[] array, final int index) {
4674 return (float[]) remove((Object) array, index);
4675 }
4676
4677 /**
4678 * <p>Removes the first occurrence of the specified element from the
4679 * specified array. All subsequent elements are shifted to the left
4680 * (subtracts one from their indices). If the array doesn't contains
4681 * such an element, no elements are removed from the array.</p>
4682 *
4683 * <p>This method returns a new array with the same elements of the input
4684 * array except the first occurrence of the specified element. The component
4685 * type of the returned array is always the same as that of the input
4686 * array.</p>
4687 *
4688 * <pre>
4689 * ArrayUtils.removeElement(null, 1.1) = null
4690 * ArrayUtils.removeElement([], 1.1) = []
4691 * ArrayUtils.removeElement([1.1], 1.2) = [1.1]
4692 * ArrayUtils.removeElement([1.1, 2.3], 1.1) = [2.3]
4693 * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
4694 * </pre>
4695 *
4696 * @param array the array to remove the element from, may be {@code null}
4697 * @param element the element to be removed
4698 * @return A new array containing the existing elements except the first
4699 * occurrence of the specified element.
4700 * @since 2.1
4701 */
4702 public static float[] removeElement(final float[] array, final float element) {
4703 final int index = indexOf(array, element);
4704 if (index == INDEX_NOT_FOUND) {
4705 return clone(array);
4706 }
4707 return remove(array, index);
4708 }
4709
4710 /**
4711 * <p>Removes the element at the specified position from the specified array.
4712 * All subsequent elements are shifted to the left (subtracts one from
4713 * their indices).</p>
4714 *
4715 * <p>This method returns a new array with the same elements of the input
4716 * array except the element on the specified position. The component
4717 * type of the returned array is always the same as that of the input
4718 * array.</p>
4719 *
4720 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4721 * will be thrown, because in that case no valid index can be specified.</p>
4722 *
4723 * <pre>
4724 * ArrayUtils.remove([1], 0) = []
4725 * ArrayUtils.remove([2, 6], 0) = [6]
4726 * ArrayUtils.remove([2, 6], 1) = [2]
4727 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
4728 * </pre>
4729 *
4730 * @param array the array to remove the element from, may not be {@code null}
4731 * @param index the position of the element to be removed
4732 * @return A new array containing the existing elements except the element
4733 * at the specified position.
4734 * @throws IndexOutOfBoundsException if the index is out of range
4735 * (index < 0 || index >= array.length), or if the array is {@code null}.
4736 * @since 2.1
4737 */
4738 public static int[] remove(final int[] array, final int index) {
4739 return (int[]) remove((Object) array, index);
4740 }
4741
4742 /**
4743 * <p>Removes the first occurrence of the specified element from the
4744 * specified array. All subsequent elements are shifted to the left
4745 * (subtracts one from their indices). If the array doesn't contains
4746 * such an element, no elements are removed from the array.</p>
4747 *
4748 * <p>This method returns a new array with the same elements of the input
4749 * array except the first occurrence of the specified element. The component
4750 * type of the returned array is always the same as that of the input
4751 * array.</p>
4752 *
4753 * <pre>
4754 * ArrayUtils.removeElement(null, 1) = null
4755 * ArrayUtils.removeElement([], 1) = []
4756 * ArrayUtils.removeElement([1], 2) = [1]
4757 * ArrayUtils.removeElement([1, 3], 1) = [3]
4758 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4759 * </pre>
4760 *
4761 * @param array the array to remove the element from, may be {@code null}
4762 * @param element the element to be removed
4763 * @return A new array containing the existing elements except the first
4764 * occurrence of the specified element.
4765 * @since 2.1
4766 */
4767 public static int[] removeElement(final int[] array, final int element) {
4768 final int index = indexOf(array, element);
4769 if (index == INDEX_NOT_FOUND) {
4770 return clone(array);
4771 }
4772 return remove(array, index);
4773 }
4774
4775 /**
4776 * <p>Removes the element at the specified position from the specified array.
4777 * All subsequent elements are shifted to the left (subtracts one from
4778 * their indices).</p>
4779 *
4780 * <p>This method returns a new array with the same elements of the input
4781 * array except the element on the specified position. The component
4782 * type of the returned array is always the same as that of the input
4783 * array.</p>
4784 *
4785 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4786 * will be thrown, because in that case no valid index can be specified.</p>
4787 *
4788 * <pre>
4789 * ArrayUtils.remove([1], 0) = []
4790 * ArrayUtils.remove([2, 6], 0) = [6]
4791 * ArrayUtils.remove([2, 6], 1) = [2]
4792 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
4793 * </pre>
4794 *
4795 * @param array the array to remove the element from, may not be {@code null}
4796 * @param index the position of the element to be removed
4797 * @return A new array containing the existing elements except the element
4798 * at the specified position.
4799 * @throws IndexOutOfBoundsException if the index is out of range
4800 * (index < 0 || index >= array.length), or if the array is {@code null}.
4801 * @since 2.1
4802 */
4803 public static long[] remove(final long[] array, final int index) {
4804 return (long[]) remove((Object) array, index);
4805 }
4806
4807 /**
4808 * <p>Removes the first occurrence of the specified element from the
4809 * specified array. All subsequent elements are shifted to the left
4810 * (subtracts one from their indices). If the array doesn't contains
4811 * such an element, no elements are removed from the array.</p>
4812 *
4813 * <p>This method returns a new array with the same elements of the input
4814 * array except the first occurrence of the specified element. The component
4815 * type of the returned array is always the same as that of the input
4816 * array.</p>
4817 *
4818 * <pre>
4819 * ArrayUtils.removeElement(null, 1) = null
4820 * ArrayUtils.removeElement([], 1) = []
4821 * ArrayUtils.removeElement([1], 2) = [1]
4822 * ArrayUtils.removeElement([1, 3], 1) = [3]
4823 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4824 * </pre>
4825 *
4826 * @param array the array to remove the element from, may be {@code null}
4827 * @param element the element to be removed
4828 * @return A new array containing the existing elements except the first
4829 * occurrence of the specified element.
4830 * @since 2.1
4831 */
4832 public static long[] removeElement(final long[] array, final long element) {
4833 final int index = indexOf(array, element);
4834 if (index == INDEX_NOT_FOUND) {
4835 return clone(array);
4836 }
4837 return remove(array, index);
4838 }
4839
4840 /**
4841 * <p>Removes the element at the specified position from the specified array.
4842 * All subsequent elements are shifted to the left (subtracts one from
4843 * their indices).</p>
4844 *
4845 * <p>This method returns a new array with the same elements of the input
4846 * array except the element on the specified position. The component
4847 * type of the returned array is always the same as that of the input
4848 * array.</p>
4849 *
4850 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4851 * will be thrown, because in that case no valid index can be specified.</p>
4852 *
4853 * <pre>
4854 * ArrayUtils.remove([1], 0) = []
4855 * ArrayUtils.remove([2, 6], 0) = [6]
4856 * ArrayUtils.remove([2, 6], 1) = [2]
4857 * ArrayUtils.remove([2, 6, 3], 1) = [2, 3]
4858 * </pre>
4859 *
4860 * @param array the array to remove the element from, may not be {@code null}
4861 * @param index the position of the element to be removed
4862 * @return A new array containing the existing elements except the element
4863 * at the specified position.
4864 * @throws IndexOutOfBoundsException if the index is out of range
4865 * (index < 0 || index >= array.length), or if the array is {@code null}.
4866 * @since 2.1
4867 */
4868 public static short[] remove(final short[] array, final int index) {
4869 return (short[]) remove((Object) array, index);
4870 }
4871
4872 /**
4873 * <p>Removes the first occurrence of the specified element from the
4874 * specified array. All subsequent elements are shifted to the left
4875 * (subtracts one from their indices). If the array doesn't contains
4876 * such an element, no elements are removed from the array.</p>
4877 *
4878 * <p>This method returns a new array with the same elements of the input
4879 * array except the first occurrence of the specified element. The component
4880 * type of the returned array is always the same as that of the input
4881 * array.</p>
4882 *
4883 * <pre>
4884 * ArrayUtils.removeElement(null, 1) = null
4885 * ArrayUtils.removeElement([], 1) = []
4886 * ArrayUtils.removeElement([1], 2) = [1]
4887 * ArrayUtils.removeElement([1, 3], 1) = [3]
4888 * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
4889 * </pre>
4890 *
4891 * @param array the array to remove the element from, may be {@code null}
4892 * @param element the element to be removed
4893 * @return A new array containing the existing elements except the first
4894 * occurrence of the specified element.
4895 * @since 2.1
4896 */
4897 public static short[] removeElement(final short[] array, final short element) {
4898 final int index = indexOf(array, element);
4899 if (index == INDEX_NOT_FOUND) {
4900 return clone(array);
4901 }
4902 return remove(array, index);
4903 }
4904
4905 /**
4906 * <p>Removes the element at the specified position from the specified array.
4907 * All subsequent elements are shifted to the left (subtracts one from
4908 * their indices).</p>
4909 *
4910 * <p>This method returns a new array with the same elements of the input
4911 * array except the element on the specified position. The component
4912 * type of the returned array is always the same as that of the input
4913 * array.</p>
4914 *
4915 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4916 * will be thrown, because in that case no valid index can be specified.</p>
4917 *
4918 * @param array the array to remove the element from, may not be {@code null}
4919 * @param index the position of the element to be removed
4920 * @return A new array containing the existing elements except the element
4921 * at the specified position.
4922 * @throws IndexOutOfBoundsException if the index is out of range
4923 * (index < 0 || index >= array.length), or if the array is {@code null}.
4924 * @since 2.1
4925 */
4926 private static Object remove(final Object array, final int index) {
4927 final int length = getLength(array);
4928 if (index < 0 || index >= length) {
4929 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
4930 }
4931
4932 final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
4933 System.arraycopy(array, 0, result, 0, index);
4934 if (index < length - 1) {
4935 System.arraycopy(array, index + 1, result, index, length - index - 1);
4936 }
4937
4938 return result;
4939 }
4940
4941 /**
4942 * <p>Removes the elements at the specified positions from the specified array.
4943 * All remaining elements are shifted to the left.</p>
4944 *
4945 * <p>This method returns a new array with the same elements of the input
4946 * array except those at the specified positions. The component
4947 * type of the returned array is always the same as that of the input
4948 * array.</p>
4949 *
4950 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
4951 * will be thrown, because in that case no valid index can be specified.</p>
4952 *
4953 * <pre>
4954 * ArrayUtils.removeAll(["a", "b", "c"], 0, 2) = ["b"]
4955 * ArrayUtils.removeAll(["a", "b", "c"], 1, 2) = ["a"]
4956 * </pre>
4957 *
4958 * @param <T> the component type of the array
4959 * @param array the array to remove the element from, may not be {@code null}
4960 * @param indices the positions of the elements to be removed
4961 * @return A new array containing the existing elements except those
4962 * at the specified positions.
4963 * @throws IndexOutOfBoundsException if any index is out of range
4964 * (index < 0 || index >= array.length), or if the array is {@code null}.
4965 * @since 3.0.1
4966 */
4967 @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
4968 public static <T> T[] removeAll(final T[] array, final int... indices) {
4969 return (T[]) removeAll((Object) array, clone(indices));
4970 }
4971
4972 /**
4973 * <p>Removes occurrences of specified elements, in specified quantities,
4974 * from the specified array. All subsequent elements are shifted left.
4975 * For any element-to-be-removed specified in greater quantities than
4976 * contained in the original array, no change occurs beyond the
4977 * removal of the existing matching items.</p>
4978 *
4979 * <p>This method returns a new array with the same elements of the input
4980 * array except for the earliest-encountered occurrences of the specified
4981 * elements. The component type of the returned array is always the same
4982 * as that of the input array.</p>
4983 *
4984 * <pre>
4985 * ArrayUtils.removeElements(null, "a", "b") = null
4986 * ArrayUtils.removeElements([], "a", "b") = []
4987 * ArrayUtils.removeElements(["a"], "b", "c") = ["a"]
4988 * ArrayUtils.removeElements(["a", "b"], "a", "c") = ["b"]
4989 * ArrayUtils.removeElements(["a", "b", "a"], "a") = ["b", "a"]
4990 * ArrayUtils.removeElements(["a", "b", "a"], "a", "a") = ["b"]
4991 * </pre>
4992 *
4993 * @param <T> the component type of the array
4994 * @param array the array to remove the element from, may be {@code null}
4995 * @param values the elements to be removed
4996 * @return A new array containing the existing elements except the
4997 * earliest-encountered occurrences of the specified elements.
4998 * @since 3.0.1
4999 */
5000 public static <T> T[] removeElements(final T[] array, final T... values) {
5001 if (isEmpty(array) || isEmpty(values)) {
5002 return clone(array);
5003 }
5004 final HashMap<T, MutableInt> occurrences = new HashMap<T, MutableInt>(values.length);
5005 for (final T v : values) {
5006 final MutableInt count = occurrences.get(v);
5007 if (count == null) {
5008 occurrences.put(v, new MutableInt(1));
5009 } else {
5010 count.increment();
5011 }
5012 }
5013 final BitSet toRemove = new BitSet();
5014 for (final Map.Entry<T, MutableInt> e : occurrences.entrySet()) {
5015 final T v = e.getKey();
5016 int found = 0;
5017 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5018 found = indexOf(array, v, found);
5019 if (found < 0) {
5020 break;
5021 }
5022 toRemove.set(found++);
5023 }
5024 }
5025 @SuppressWarnings("unchecked") // removeAll() always creates an array of the same type as its input
5026 final
5027 T[] result = (T[]) removeAll(array, toRemove);
5028 return result;
5029 }
5030
5031 /**
5032 * <p>Removes the elements at the specified positions from the specified array.
5033 * All remaining elements are shifted to the left.</p>
5034 *
5035 * <p>This method returns a new array with the same elements of the input
5036 * array except those at the specified positions. The component
5037 * type of the returned array is always the same as that of the input
5038 * array.</p>
5039 *
5040 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5041 * will be thrown, because in that case no valid index can be specified.</p>
5042 *
5043 * <pre>
5044 * ArrayUtils.removeAll([1], 0) = []
5045 * ArrayUtils.removeAll([2, 6], 0) = [6]
5046 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5047 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5048 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5049 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5050 * </pre>
5051 *
5052 * @param array the array to remove the element from, may not be {@code null}
5053 * @param indices the positions of the elements to be removed
5054 * @return A new array containing the existing elements except those
5055 * at the specified positions.
5056 * @throws IndexOutOfBoundsException if any index is out of range
5057 * (index < 0 || index >= array.length), or if the array is {@code null}.
5058 * @since 3.0.1
5059 */
5060 public static byte[] removeAll(final byte[] array, final int... indices) {
5061 return (byte[]) removeAll((Object) array, clone(indices));
5062 }
5063
5064 /**
5065 * <p>Removes occurrences of specified elements, in specified quantities,
5066 * from the specified array. All subsequent elements are shifted left.
5067 * For any element-to-be-removed specified in greater quantities than
5068 * contained in the original array, no change occurs beyond the
5069 * removal of the existing matching items.</p>
5070 *
5071 * <p>This method returns a new array with the same elements of the input
5072 * array except for the earliest-encountered occurrences of the specified
5073 * elements. The component type of the returned array is always the same
5074 * as that of the input array.</p>
5075 *
5076 * <pre>
5077 * ArrayUtils.removeElements(null, 1, 2) = null
5078 * ArrayUtils.removeElements([], 1, 2) = []
5079 * ArrayUtils.removeElements([1], 2, 3) = [1]
5080 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5081 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5082 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5083 * </pre>
5084 *
5085 * @param array the array to remove the element from, may be {@code null}
5086 * @param values the elements to be removed
5087 * @return A new array containing the existing elements except the
5088 * earliest-encountered occurrences of the specified elements.
5089 * @since 3.0.1
5090 */
5091 public static byte[] removeElements(final byte[] array, final byte... values) {
5092 if (isEmpty(array) || isEmpty(values)) {
5093 return clone(array);
5094 }
5095 final HashMap<Byte, MutableInt> occurrences = new HashMap<Byte, MutableInt>(values.length);
5096 for (final byte v : values) {
5097 final Byte boxed = Byte.valueOf(v);
5098 final MutableInt count = occurrences.get(boxed);
5099 if (count == null) {
5100 occurrences.put(boxed, new MutableInt(1));
5101 } else {
5102 count.increment();
5103 }
5104 }
5105 final BitSet toRemove = new BitSet();
5106 for (final Map.Entry<Byte, MutableInt> e : occurrences.entrySet()) {
5107 final Byte v = e.getKey();
5108 int found = 0;
5109 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5110 found = indexOf(array, v.byteValue(), found);
5111 if (found < 0) {
5112 break;
5113 }
5114 toRemove.set(found++);
5115 }
5116 }
5117 return (byte[]) removeAll(array, toRemove);
5118 }
5119
5120 /**
5121 * <p>Removes the elements at the specified positions from the specified array.
5122 * All remaining elements are shifted to the left.</p>
5123 *
5124 * <p>This method returns a new array with the same elements of the input
5125 * array except those at the specified positions. The component
5126 * type of the returned array is always the same as that of the input
5127 * array.</p>
5128 *
5129 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5130 * will be thrown, because in that case no valid index can be specified.</p>
5131 *
5132 * <pre>
5133 * ArrayUtils.removeAll([1], 0) = []
5134 * ArrayUtils.removeAll([2, 6], 0) = [6]
5135 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5136 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5137 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5138 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5139 * </pre>
5140 *
5141 * @param array the array to remove the element from, may not be {@code null}
5142 * @param indices the positions of the elements to be removed
5143 * @return A new array containing the existing elements except those
5144 * at the specified positions.
5145 * @throws IndexOutOfBoundsException if any index is out of range
5146 * (index < 0 || index >= array.length), or if the array is {@code null}.
5147 * @since 3.0.1
5148 */
5149 public static short[] removeAll(final short[] array, final int... indices) {
5150 return (short[]) removeAll((Object) array, clone(indices));
5151 }
5152
5153 /**
5154 * <p>Removes occurrences of specified elements, in specified quantities,
5155 * from the specified array. All subsequent elements are shifted left.
5156 * For any element-to-be-removed specified in greater quantities than
5157 * contained in the original array, no change occurs beyond the
5158 * removal of the existing matching items.</p>
5159 *
5160 * <p>This method returns a new array with the same elements of the input
5161 * array except for the earliest-encountered occurrences of the specified
5162 * elements. The component type of the returned array is always the same
5163 * as that of the input array.</p>
5164 *
5165 * <pre>
5166 * ArrayUtils.removeElements(null, 1, 2) = null
5167 * ArrayUtils.removeElements([], 1, 2) = []
5168 * ArrayUtils.removeElements([1], 2, 3) = [1]
5169 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5170 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5171 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5172 * </pre>
5173 *
5174 * @param array the array to remove the element from, may be {@code null}
5175 * @param values the elements to be removed
5176 * @return A new array containing the existing elements except the
5177 * earliest-encountered occurrences of the specified elements.
5178 * @since 3.0.1
5179 */
5180 public static short[] removeElements(final short[] array, final short... values) {
5181 if (isEmpty(array) || isEmpty(values)) {
5182 return clone(array);
5183 }
5184 final HashMap<Short, MutableInt> occurrences = new HashMap<Short, MutableInt>(values.length);
5185 for (final short v : values) {
5186 final Short boxed = Short.valueOf(v);
5187 final MutableInt count = occurrences.get(boxed);
5188 if (count == null) {
5189 occurrences.put(boxed, new MutableInt(1));
5190 } else {
5191 count.increment();
5192 }
5193 }
5194 final BitSet toRemove = new BitSet();
5195 for (final Map.Entry<Short, MutableInt> e : occurrences.entrySet()) {
5196 final Short v = e.getKey();
5197 int found = 0;
5198 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5199 found = indexOf(array, v.shortValue(), found);
5200 if (found < 0) {
5201 break;
5202 }
5203 toRemove.set(found++);
5204 }
5205 }
5206 return (short[]) removeAll(array, toRemove);
5207 }
5208
5209 /**
5210 * <p>Removes the elements at the specified positions from the specified array.
5211 * All remaining elements are shifted to the left.</p>
5212 *
5213 * <p>This method returns a new array with the same elements of the input
5214 * array except those at the specified positions. The component
5215 * type of the returned array is always the same as that of the input
5216 * array.</p>
5217 *
5218 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5219 * will be thrown, because in that case no valid index can be specified.</p>
5220 *
5221 * <pre>
5222 * ArrayUtils.removeAll([1], 0) = []
5223 * ArrayUtils.removeAll([2, 6], 0) = [6]
5224 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5225 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5226 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5227 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5228 * </pre>
5229 *
5230 * @param array the array to remove the element from, may not be {@code null}
5231 * @param indices the positions of the elements to be removed
5232 * @return A new array containing the existing elements except those
5233 * at the specified positions.
5234 * @throws IndexOutOfBoundsException if any index is out of range
5235 * (index < 0 || index >= array.length), or if the array is {@code null}.
5236 * @since 3.0.1
5237 */
5238 public static int[] removeAll(final int[] array, final int... indices) {
5239 return (int[]) removeAll((Object) array, clone(indices));
5240 }
5241
5242 /**
5243 * <p>Removes occurrences of specified elements, in specified quantities,
5244 * from the specified array. All subsequent elements are shifted left.
5245 * For any element-to-be-removed specified in greater quantities than
5246 * contained in the original array, no change occurs beyond the
5247 * removal of the existing matching items.</p>
5248 *
5249 * <p>This method returns a new array with the same elements of the input
5250 * array except for the earliest-encountered occurrences of the specified
5251 * elements. The component type of the returned array is always the same
5252 * as that of the input array.</p>
5253 *
5254 * <pre>
5255 * ArrayUtils.removeElements(null, 1, 2) = null
5256 * ArrayUtils.removeElements([], 1, 2) = []
5257 * ArrayUtils.removeElements([1], 2, 3) = [1]
5258 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5259 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5260 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5261 * </pre>
5262 *
5263 * @param array the array to remove the element from, may be {@code null}
5264 * @param values the elements to be removed
5265 * @return A new array containing the existing elements except the
5266 * earliest-encountered occurrences of the specified elements.
5267 * @since 3.0.1
5268 */
5269 public static int[] removeElements(final int[] array, final int... values) {
5270 if (isEmpty(array) || isEmpty(values)) {
5271 return clone(array);
5272 }
5273 final HashMap<Integer, MutableInt> occurrences = new HashMap<Integer, MutableInt>(values.length);
5274 for (final int v : values) {
5275 final Integer boxed = Integer.valueOf(v);
5276 final MutableInt count = occurrences.get(boxed);
5277 if (count == null) {
5278 occurrences.put(boxed, new MutableInt(1));
5279 } else {
5280 count.increment();
5281 }
5282 }
5283 final BitSet toRemove = new BitSet();
5284 for (final Map.Entry<Integer, MutableInt> e : occurrences.entrySet()) {
5285 final Integer v = e.getKey();
5286 int found = 0;
5287 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5288 found = indexOf(array, v.intValue(), found);
5289 if (found < 0) {
5290 break;
5291 }
5292 toRemove.set(found++);
5293 }
5294 }
5295 return (int[]) removeAll(array, toRemove);
5296 }
5297
5298 /**
5299 * <p>Removes the elements at the specified positions from the specified array.
5300 * All remaining elements are shifted to the left.</p>
5301 *
5302 * <p>This method returns a new array with the same elements of the input
5303 * array except those at the specified positions. The component
5304 * type of the returned array is always the same as that of the input
5305 * array.</p>
5306 *
5307 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5308 * will be thrown, because in that case no valid index can be specified.</p>
5309 *
5310 * <pre>
5311 * ArrayUtils.removeAll([1], 0) = []
5312 * ArrayUtils.removeAll([2, 6], 0) = [6]
5313 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5314 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5315 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5316 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5317 * </pre>
5318 *
5319 * @param array the array to remove the element from, may not be {@code null}
5320 * @param indices the positions of the elements to be removed
5321 * @return A new array containing the existing elements except those
5322 * at the specified positions.
5323 * @throws IndexOutOfBoundsException if any index is out of range
5324 * (index < 0 || index >= array.length), or if the array is {@code null}.
5325 * @since 3.0.1
5326 */
5327 public static char[] removeAll(final char[] array, final int... indices) {
5328 return (char[]) removeAll((Object) array, clone(indices));
5329 }
5330
5331 /**
5332 * <p>Removes occurrences of specified elements, in specified quantities,
5333 * from the specified array. All subsequent elements are shifted left.
5334 * For any element-to-be-removed specified in greater quantities than
5335 * contained in the original array, no change occurs beyond the
5336 * removal of the existing matching items.</p>
5337 *
5338 * <p>This method returns a new array with the same elements of the input
5339 * array except for the earliest-encountered occurrences of the specified
5340 * elements. The component type of the returned array is always the same
5341 * as that of the input array.</p>
5342 *
5343 * <pre>
5344 * ArrayUtils.removeElements(null, 1, 2) = null
5345 * ArrayUtils.removeElements([], 1, 2) = []
5346 * ArrayUtils.removeElements([1], 2, 3) = [1]
5347 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5348 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5349 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5350 * </pre>
5351 *
5352 * @param array the array to remove the element from, may be {@code null}
5353 * @param values the elements to be removed
5354 * @return A new array containing the existing elements except the
5355 * earliest-encountered occurrences of the specified elements.
5356 * @since 3.0.1
5357 */
5358 public static char[] removeElements(final char[] array, final char... values) {
5359 if (isEmpty(array) || isEmpty(values)) {
5360 return clone(array);
5361 }
5362 final HashMap<Character, MutableInt> occurrences = new HashMap<Character, MutableInt>(values.length);
5363 for (final char v : values) {
5364 final Character boxed = Character.valueOf(v);
5365 final MutableInt count = occurrences.get(boxed);
5366 if (count == null) {
5367 occurrences.put(boxed, new MutableInt(1));
5368 } else {
5369 count.increment();
5370 }
5371 }
5372 final BitSet toRemove = new BitSet();
5373 for (final Map.Entry<Character, MutableInt> e : occurrences.entrySet()) {
5374 final Character v = e.getKey();
5375 int found = 0;
5376 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5377 found = indexOf(array, v.charValue(), found);
5378 if (found < 0) {
5379 break;
5380 }
5381 toRemove.set(found++);
5382 }
5383 }
5384 return (char[]) removeAll(array, toRemove);
5385 }
5386
5387 /**
5388 * <p>Removes the elements at the specified positions from the specified array.
5389 * All remaining elements are shifted to the left.</p>
5390 *
5391 * <p>This method returns a new array with the same elements of the input
5392 * array except those at the specified positions. The component
5393 * type of the returned array is always the same as that of the input
5394 * array.</p>
5395 *
5396 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5397 * will be thrown, because in that case no valid index can be specified.</p>
5398 *
5399 * <pre>
5400 * ArrayUtils.removeAll([1], 0) = []
5401 * ArrayUtils.removeAll([2, 6], 0) = [6]
5402 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5403 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5404 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5405 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5406 * </pre>
5407 *
5408 * @param array the array to remove the element from, may not be {@code null}
5409 * @param indices the positions of the elements to be removed
5410 * @return A new array containing the existing elements except those
5411 * at the specified positions.
5412 * @throws IndexOutOfBoundsException if any index is out of range
5413 * (index < 0 || index >= array.length), or if the array is {@code null}.
5414 * @since 3.0.1
5415 */
5416 public static long[] removeAll(final long[] array, final int... indices) {
5417 return (long[]) removeAll((Object) array, clone(indices));
5418 }
5419
5420 /**
5421 * <p>Removes occurrences of specified elements, in specified quantities,
5422 * from the specified array. All subsequent elements are shifted left.
5423 * For any element-to-be-removed specified in greater quantities than
5424 * contained in the original array, no change occurs beyond the
5425 * removal of the existing matching items.</p>
5426 *
5427 * <p>This method returns a new array with the same elements of the input
5428 * array except for the earliest-encountered occurrences of the specified
5429 * elements. The component type of the returned array is always the same
5430 * as that of the input array.</p>
5431 *
5432 * <pre>
5433 * ArrayUtils.removeElements(null, 1, 2) = null
5434 * ArrayUtils.removeElements([], 1, 2) = []
5435 * ArrayUtils.removeElements([1], 2, 3) = [1]
5436 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5437 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5438 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5439 * </pre>
5440 *
5441 * @param array the array to remove the element from, may be {@code null}
5442 * @param values the elements to be removed
5443 * @return A new array containing the existing elements except the
5444 * earliest-encountered occurrences of the specified elements.
5445 * @since 3.0.1
5446 */
5447 public static long[] removeElements(final long[] array, final long... values) {
5448 if (isEmpty(array) || isEmpty(values)) {
5449 return clone(array);
5450 }
5451 final HashMap<Long, MutableInt> occurrences = new HashMap<Long, MutableInt>(values.length);
5452 for (final long v : values) {
5453 final Long boxed = Long.valueOf(v);
5454 final MutableInt count = occurrences.get(boxed);
5455 if (count == null) {
5456 occurrences.put(boxed, new MutableInt(1));
5457 } else {
5458 count.increment();
5459 }
5460 }
5461 final BitSet toRemove = new BitSet();
5462 for (final Map.Entry<Long, MutableInt> e : occurrences.entrySet()) {
5463 final Long v = e.getKey();
5464 int found = 0;
5465 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5466 found = indexOf(array, v.longValue(), found);
5467 if (found < 0) {
5468 break;
5469 }
5470 toRemove.set(found++);
5471 }
5472 }
5473 return (long[]) removeAll(array, toRemove);
5474 }
5475
5476 /**
5477 * <p>Removes the elements at the specified positions from the specified array.
5478 * All remaining elements are shifted to the left.</p>
5479 *
5480 * <p>This method returns a new array with the same elements of the input
5481 * array except those at the specified positions. The component
5482 * type of the returned array is always the same as that of the input
5483 * array.</p>
5484 *
5485 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5486 * will be thrown, because in that case no valid index can be specified.</p>
5487 *
5488 * <pre>
5489 * ArrayUtils.removeAll([1], 0) = []
5490 * ArrayUtils.removeAll([2, 6], 0) = [6]
5491 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5492 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5493 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5494 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5495 * </pre>
5496 *
5497 * @param array the array to remove the element from, may not be {@code null}
5498 * @param indices the positions of the elements to be removed
5499 * @return A new array containing the existing elements except those
5500 * at the specified positions.
5501 * @throws IndexOutOfBoundsException if any index is out of range
5502 * (index < 0 || index >= array.length), or if the array is {@code null}.
5503 * @since 3.0.1
5504 */
5505 public static float[] removeAll(final float[] array, final int... indices) {
5506 return (float[]) removeAll((Object) array, clone(indices));
5507 }
5508
5509 /**
5510 * <p>Removes occurrences of specified elements, in specified quantities,
5511 * from the specified array. All subsequent elements are shifted left.
5512 * For any element-to-be-removed specified in greater quantities than
5513 * contained in the original array, no change occurs beyond the
5514 * removal of the existing matching items.</p>
5515 *
5516 * <p>This method returns a new array with the same elements of the input
5517 * array except for the earliest-encountered occurrences of the specified
5518 * elements. The component type of the returned array is always the same
5519 * as that of the input array.</p>
5520 *
5521 * <pre>
5522 * ArrayUtils.removeElements(null, 1, 2) = null
5523 * ArrayUtils.removeElements([], 1, 2) = []
5524 * ArrayUtils.removeElements([1], 2, 3) = [1]
5525 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5526 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5527 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5528 * </pre>
5529 *
5530 * @param array the array to remove the element from, may be {@code null}
5531 * @param values the elements to be removed
5532 * @return A new array containing the existing elements except the
5533 * earliest-encountered occurrences of the specified elements.
5534 * @since 3.0.1
5535 */
5536 public static float[] removeElements(final float[] array, final float... values) {
5537 if (isEmpty(array) || isEmpty(values)) {
5538 return clone(array);
5539 }
5540 final HashMap<Float, MutableInt> occurrences = new HashMap<Float, MutableInt>(values.length);
5541 for (final float v : values) {
5542 final Float boxed = Float.valueOf(v);
5543 final MutableInt count = occurrences.get(boxed);
5544 if (count == null) {
5545 occurrences.put(boxed, new MutableInt(1));
5546 } else {
5547 count.increment();
5548 }
5549 }
5550 final BitSet toRemove = new BitSet();
5551 for (final Map.Entry<Float, MutableInt> e : occurrences.entrySet()) {
5552 final Float v = e.getKey();
5553 int found = 0;
5554 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5555 found = indexOf(array, v.floatValue(), found);
5556 if (found < 0) {
5557 break;
5558 }
5559 toRemove.set(found++);
5560 }
5561 }
5562 return (float[]) removeAll(array, toRemove);
5563 }
5564
5565 /**
5566 * <p>Removes the elements at the specified positions from the specified array.
5567 * All remaining elements are shifted to the left.</p>
5568 *
5569 * <p>This method returns a new array with the same elements of the input
5570 * array except those at the specified positions. The component
5571 * type of the returned array is always the same as that of the input
5572 * array.</p>
5573 *
5574 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5575 * will be thrown, because in that case no valid index can be specified.</p>
5576 *
5577 * <pre>
5578 * ArrayUtils.removeAll([1], 0) = []
5579 * ArrayUtils.removeAll([2, 6], 0) = [6]
5580 * ArrayUtils.removeAll([2, 6], 0, 1) = []
5581 * ArrayUtils.removeAll([2, 6, 3], 1, 2) = [2]
5582 * ArrayUtils.removeAll([2, 6, 3], 0, 2) = [6]
5583 * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
5584 * </pre>
5585 *
5586 * @param array the array to remove the element from, may not be {@code null}
5587 * @param indices the positions of the elements to be removed
5588 * @return A new array containing the existing elements except those
5589 * at the specified positions.
5590 * @throws IndexOutOfBoundsException if any index is out of range
5591 * (index < 0 || index >= array.length), or if the array is {@code null}.
5592 * @since 3.0.1
5593 */
5594 public static double[] removeAll(final double[] array, final int... indices) {
5595 return (double[]) removeAll((Object) array, clone(indices));
5596 }
5597
5598 /**
5599 * <p>Removes occurrences of specified elements, in specified quantities,
5600 * from the specified array. All subsequent elements are shifted left.
5601 * For any element-to-be-removed specified in greater quantities than
5602 * contained in the original array, no change occurs beyond the
5603 * removal of the existing matching items.</p>
5604 *
5605 * <p>This method returns a new array with the same elements of the input
5606 * array except for the earliest-encountered occurrences of the specified
5607 * elements. The component type of the returned array is always the same
5608 * as that of the input array.</p>
5609 *
5610 * <pre>
5611 * ArrayUtils.removeElements(null, 1, 2) = null
5612 * ArrayUtils.removeElements([], 1, 2) = []
5613 * ArrayUtils.removeElements([1], 2, 3) = [1]
5614 * ArrayUtils.removeElements([1, 3], 1, 2) = [3]
5615 * ArrayUtils.removeElements([1, 3, 1], 1) = [3, 1]
5616 * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
5617 * </pre>
5618 *
5619 * @param array the array to remove the element from, may be {@code null}
5620 * @param values the elements to be removed
5621 * @return A new array containing the existing elements except the
5622 * earliest-encountered occurrences of the specified elements.
5623 * @since 3.0.1
5624 */
5625 public static double[] removeElements(final double[] array, final double... values) {
5626 if (isEmpty(array) || isEmpty(values)) {
5627 return clone(array);
5628 }
5629 final HashMap<Double, MutableInt> occurrences = new HashMap<Double, MutableInt>(values.length);
5630 for (final double v : values) {
5631 final Double boxed = Double.valueOf(v);
5632 final MutableInt count = occurrences.get(boxed);
5633 if (count == null) {
5634 occurrences.put(boxed, new MutableInt(1));
5635 } else {
5636 count.increment();
5637 }
5638 }
5639 final BitSet toRemove = new BitSet();
5640 for (final Map.Entry<Double, MutableInt> e : occurrences.entrySet()) {
5641 final Double v = e.getKey();
5642 int found = 0;
5643 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5644 found = indexOf(array, v.doubleValue(), found);
5645 if (found < 0) {
5646 break;
5647 }
5648 toRemove.set(found++);
5649 }
5650 }
5651 return (double[]) removeAll(array, toRemove);
5652 }
5653
5654 /**
5655 * <p>Removes the elements at the specified positions from the specified array.
5656 * All remaining elements are shifted to the left.</p>
5657 *
5658 * <p>This method returns a new array with the same elements of the input
5659 * array except those at the specified positions. The component
5660 * type of the returned array is always the same as that of the input
5661 * array.</p>
5662 *
5663 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
5664 * will be thrown, because in that case no valid index can be specified.</p>
5665 *
5666 * <pre>
5667 * ArrayUtils.removeAll([true, false, true], 0, 2) = [false]
5668 * ArrayUtils.removeAll([true, false, true], 1, 2) = [true]
5669 * </pre>
5670 *
5671 * @param array the array to remove the element from, may not be {@code null}
5672 * @param indices the positions of the elements to be removed
5673 * @return A new array containing the existing elements except those
5674 * at the specified positions.
5675 * @throws IndexOutOfBoundsException if any index is out of range
5676 * (index < 0 || index >= array.length), or if the array is {@code null}.
5677 * @since 3.0.1
5678 */
5679 public static boolean[] removeAll(final boolean[] array, final int... indices) {
5680 return (boolean[]) removeAll((Object) array, clone(indices));
5681 }
5682
5683 /**
5684 * <p>Removes occurrences of specified elements, in specified quantities,
5685 * from the specified array. All subsequent elements are shifted left.
5686 * For any element-to-be-removed specified in greater quantities than
5687 * contained in the original array, no change occurs beyond the
5688 * removal of the existing matching items.</p>
5689 *
5690 * <p>This method returns a new array with the same elements of the input
5691 * array except for the earliest-encountered occurrences of the specified
5692 * elements. The component type of the returned array is always the same
5693 * as that of the input array.</p>
5694 *
5695 * <pre>
5696 * ArrayUtils.removeElements(null, true, false) = null
5697 * ArrayUtils.removeElements([], true, false) = []
5698 * ArrayUtils.removeElements([true], false, false) = [true]
5699 * ArrayUtils.removeElements([true, false], true, true) = [false]
5700 * ArrayUtils.removeElements([true, false, true], true) = [false, true]
5701 * ArrayUtils.removeElements([true, false, true], true, true) = [false]
5702 * </pre>
5703 *
5704 * @param array the array to remove the element from, may be {@code null}
5705 * @param values the elements to be removed
5706 * @return A new array containing the existing elements except the
5707 * earliest-encountered occurrences of the specified elements.
5708 * @since 3.0.1
5709 */
5710 public static boolean[] removeElements(final boolean[] array, final boolean... values) {
5711 if (isEmpty(array) || isEmpty(values)) {
5712 return clone(array);
5713 }
5714 final HashMap<Boolean, MutableInt> occurrences = new HashMap<Boolean, MutableInt>(2); // only two possible values here
5715 for (final boolean v : values) {
5716 final Boolean boxed = Boolean.valueOf(v);
5717 final MutableInt count = occurrences.get(boxed);
5718 if (count == null) {
5719 occurrences.put(boxed, new MutableInt(1));
5720 } else {
5721 count.increment();
5722 }
5723 }
5724 final BitSet toRemove = new BitSet();
5725 for (final Map.Entry<Boolean, MutableInt> e : occurrences.entrySet()) {
5726 final Boolean v = e.getKey();
5727 int found = 0;
5728 for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
5729 found = indexOf(array, v.booleanValue(), found);
5730 if (found < 0) {
5731 break;
5732 }
5733 toRemove.set(found++);
5734 }
5735 }
5736 return (boolean[]) removeAll(array, toRemove);
5737 }
5738
5739 /**
5740 * Removes multiple array elements specified by index.
5741 * @param array source
5742 * @param indices to remove, WILL BE SORTED--so only clones of user-owned arrays!
5743 * @return new array of same type minus elements specified by unique values of {@code indices}
5744 * @since 3.0.1
5745 */
5746 // package protected for access by unit tests
5747 static Object removeAll(final Object array, final int... indices) {
5748 final int length = getLength(array);
5749 int diff = 0; // number of distinct indexes, i.e. number of entries that will be removed
5750
5751 if (isNotEmpty(indices)) {
5752 Arrays.sort(indices);
5753
5754 int i = indices.length;
5755 int prevIndex = length;
5756 while (--i >= 0) {
5757 final int index = indices[i];
5758 if (index < 0 || index >= length) {
5759 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
5760 }
5761 if (index >= prevIndex) {
5762 continue;
5763 }
5764 diff++;
5765 prevIndex = index;
5766 }
5767 }
5768 final Object result = Array.newInstance(array.getClass().getComponentType(), length - diff);
5769 if (diff < length) {
5770 int end = length; // index just after last copy
5771 int dest = length - diff; // number of entries so far not copied
5772 for (int i = indices.length - 1; i >= 0; i--) {
5773 final int index = indices[i];
5774 if (end - index > 1) { // same as (cp > 0)
5775 final int cp = end - index - 1;
5776 dest -= cp;
5777 System.arraycopy(array, index + 1, result, dest, cp);
5778 // Afer this copy, we still have room for dest items.
5779 }
5780 end = index;
5781 }
5782 if (end > 0) {
5783 System.arraycopy(array, 0, result, 0, end);
5784 }
5785 }
5786 return result;
5787 }
5788
5789 /**
5790 * Removes multiple array elements specified by indices.
5791 *
5792 * @param array source
5793 * @param indices to remove
5794 * @return new array of same type minus elements specified by the set bits in {@code indices}
5795 * @since 3.2
5796 */
5797 // package protected for access by unit tests
5798 static Object removeAll(final Object array, final BitSet indices) {
5799 final int srcLength = ArrayUtils.getLength(array);
5800 // No need to check maxIndex here, because method only currently called from removeElements()
5801 // which guarantee to generate on;y valid bit entries.
5802 // final int maxIndex = indices.length();
5803 // if (maxIndex > srcLength) {
5804 // throw new IndexOutOfBoundsException("Index: " + (maxIndex-1) + ", Length: " + srcLength);
5805 // }
5806 final int removals = indices.cardinality(); // true bits are items to remove
5807 final Object result = Array.newInstance(array.getClass().getComponentType(), srcLength - removals);
5808 int srcIndex=0;
5809 int destIndex=0;
5810 int count;
5811 int set;
5812 while((set = indices.nextSetBit(srcIndex)) != -1){
5813 count = set - srcIndex;
5814 if (count > 0) {
5815 System.arraycopy(array, srcIndex, result, destIndex, count);
5816 destIndex += count;
5817 }
5818 srcIndex = indices.nextClearBit(set);
5819 }
5820 count = srcLength - srcIndex;
5821 if (count > 0) {
5822 System.arraycopy(array, srcIndex, result, destIndex, count);
5823 }
5824 return result;
5825 }
5826 }