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.lang;
18
19 import java.lang.reflect.Array;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import org.apache.commons.lang.builder.EqualsBuilder;
24 import org.apache.commons.lang.builder.HashCodeBuilder;
25 import org.apache.commons.lang.builder.ToStringBuilder;
26 import org.apache.commons.lang.builder.ToStringStyle;
27
28 /**
29 * <p>Operations on arrays, primitive arrays (like <code>int[]</code>) and
30 * primitive wrapper arrays (like <code>Integer[]</code>).</p>
31 *
32 * <p>This class tries to handle <code>null</code> input gracefully.
33 * An exception will not be thrown for a <code>null</code>
34 * array input. However, an Object array that contains a <code>null</code>
35 * element may throw an exception. Each method documents its behaviour.</p>
36 *
37 * @author Stephen Colebourne
38 * @author Moritz Petersen
39 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
40 * @author Nikolay Metchev
41 * @author Matthew Hawthorne
42 * @author Tim O'Brien
43 * @author Pete Gieser
44 * @author Gary Gregory
45 * @author <a href="mailto:equinus100@hotmail.com">Ashwin S</a>
46 * @author Maarten Coene
47 * @since 2.0
48 * @version $Id: ArrayUtils.java 632503 2008-03-01 00:21:52Z ggregory $
49 */
50 public class ArrayUtils {
51
52 /**
53 * An empty immutable <code>Object</code> array.
54 */
55 public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
56 /**
57 * An empty immutable <code>Class</code> array.
58 */
59 public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
60 /**
61 * An empty immutable <code>String</code> array.
62 */
63 public static final String[] EMPTY_STRING_ARRAY = new String[0];
64 /**
65 * An empty immutable <code>long</code> array.
66 */
67 public static final long[] EMPTY_LONG_ARRAY = new long[0];
68 /**
69 * An empty immutable <code>Long</code> array.
70 */
71 public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
72 /**
73 * An empty immutable <code>int</code> array.
74 */
75 public static final int[] EMPTY_INT_ARRAY = new int[0];
76 /**
77 * An empty immutable <code>Integer</code> array.
78 */
79 public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
80 /**
81 * An empty immutable <code>short</code> array.
82 */
83 public static final short[] EMPTY_SHORT_ARRAY = new short[0];
84 /**
85 * An empty immutable <code>Short</code> array.
86 */
87 public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
88 /**
89 * An empty immutable <code>byte</code> array.
90 */
91 public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
92 /**
93 * An empty immutable <code>Byte</code> array.
94 */
95 public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
96 /**
97 * An empty immutable <code>double</code> array.
98 */
99 public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
100 /**
101 * An empty immutable <code>Double</code> array.
102 */
103 public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
104 /**
105 * An empty immutable <code>float</code> array.
106 */
107 public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
108 /**
109 * An empty immutable <code>Float</code> array.
110 */
111 public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
112 /**
113 * An empty immutable <code>boolean</code> array.
114 */
115 public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
116 /**
117 * An empty immutable <code>Boolean</code> array.
118 */
119 public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
120 /**
121 * An empty immutable <code>char</code> array.
122 */
123 public static final char[] EMPTY_CHAR_ARRAY = new char[0];
124 /**
125 * An empty immutable <code>Character</code> array.
126 */
127 public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
128
129 /**
130 * The index value when an element is not found in a list or array: <code>-1</code>.
131 * This value is returned by methods in this class and can also be used in comparisons with values returned by
132 * various method from {@link java.util.List}.
133 */
134 public static final int INDEX_NOT_FOUND = -1;
135
136 /**
137 * <p>ArrayUtils instances should NOT be constructed in standard programming.
138 * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
139 *
140 * <p>This constructor is public to permit tools that require a JavaBean instance
141 * to operate.</p>
142 */
143 public ArrayUtils() {
144 super();
145 }
146
147 // Basic methods handling multi-dimensional arrays
148 //-----------------------------------------------------------------------
149 /**
150 * <p>Outputs an array as a String, treating <code>null</code> as an empty array.</p>
151 *
152 * <p>Multi-dimensional arrays are handled correctly, including
153 * multi-dimensional primitive arrays.</p>
154 *
155 * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
156 *
157 * @param array the array to get a toString for, may be <code>null</code>
158 * @return a String representation of the array, '{}' if null array input
159 */
160 public static String toString(Object array) {
161 return toString(array, "{}");
162 }
163
164 /**
165 * <p>Outputs an array as a String handling <code>null</code>s.</p>
166 *
167 * <p>Multi-dimensional arrays are handled correctly, including
168 * multi-dimensional primitive arrays.</p>
169 *
170 * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
171 *
172 * @param array the array to get a toString for, may be <code>null</code>
173 * @param stringIfNull the String to return if the array is <code>null</code>
174 * @return a String representation of the array
175 */
176 public static String toString(Object array, String stringIfNull) {
177 if (array == null) {
178 return stringIfNull;
179 }
180 return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
181 }
182
183 /**
184 * <p>Get a hashCode for an array handling multi-dimensional arrays correctly.</p>
185 *
186 * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
187 *
188 * @param array the array to get a hashCode for, may be <code>null</code>
189 * @return a hashCode for the array, zero if null array input
190 */
191 public static int hashCode(Object array) {
192 return new HashCodeBuilder().append(array).toHashCode();
193 }
194
195 /**
196 * <p>Compares two arrays, using equals(), handling multi-dimensional arrays
197 * correctly.</p>
198 *
199 * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
200 *
201 * @param array1 the left hand array to compare, may be <code>null</code>
202 * @param array2 the right hand array to compare, may be <code>null</code>
203 * @return <code>true</code> if the arrays are equal
204 */
205 public static boolean isEquals(Object array1, Object array2) {
206 return new EqualsBuilder().append(array1, array2).isEquals();
207 }
208
209 // To map
210 //-----------------------------------------------------------------------
211 /**
212 * <p>Converts the given array into a {@link java.util.Map}. Each element of the array
213 * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
214 * elements, where the first element is used as key and the second as
215 * value.</p>
216 *
217 * <p>This method can be used to initialize:</p>
218 * <pre>
219 * // Create a Map mapping colors.
220 * Map colorMap = MapUtils.toMap(new String[][] {{
221 * {"RED", "#FF0000"},
222 * {"GREEN", "#00FF00"},
223 * {"BLUE", "#0000FF"}});
224 * </pre>
225 *
226 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
227 *
228 * @param array an array whose elements are either a {@link java.util.Map.Entry} or
229 * an Array containing at least two elements, may be <code>null</code>
230 * @return a <code>Map</code> that was created from the array
231 * @throws IllegalArgumentException if one element of this Array is
232 * itself an Array containing less then two elements
233 * @throws IllegalArgumentException if the array contains elements other
234 * than {@link java.util.Map.Entry} and an Array
235 */
236 public static Map toMap(Object[] array) {
237 if (array == null) {
238 return null;
239 }
240 final Map map = new HashMap((int) (array.length * 1.5));
241 for (int i = 0; i < array.length; i++) {
242 Object object = array[i];
243 if (object instanceof Map.Entry) {
244 Map.Entry entry = (Map.Entry) object;
245 map.put(entry.getKey(), entry.getValue());
246 } else if (object instanceof Object[]) {
247 Object[] entry = (Object[]) object;
248 if (entry.length < 2) {
249 throw new IllegalArgumentException("Array element " + i + ", '"
250 + object
251 + "', has a length less than 2");
252 }
253 map.put(entry[0], entry[1]);
254 } else {
255 throw new IllegalArgumentException("Array element " + i + ", '"
256 + object
257 + "', is neither of type Map.Entry nor an Array");
258 }
259 }
260 return map;
261 }
262
263 // Clone
264 //-----------------------------------------------------------------------
265 /**
266 * <p>Shallow clones an array returning a typecast result and handling
267 * <code>null</code>.</p>
268 *
269 * <p>The objects in the array are not cloned, thus there is no special
270 * handling for multi-dimensional arrays.</p>
271 *
272 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
273 *
274 * @param array the array to shallow clone, may be <code>null</code>
275 * @return the cloned array, <code>null</code> if <code>null</code> input
276 */
277 public static Object[] clone(Object[] array) {
278 if (array == null) {
279 return null;
280 }
281 return (Object[]) array.clone();
282 }
283
284 /**
285 * <p>Clones an array returning a typecast result and handling
286 * <code>null</code>.</p>
287 *
288 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
289 *
290 * @param array the array to clone, may be <code>null</code>
291 * @return the cloned array, <code>null</code> if <code>null</code> input
292 */
293 public static long[] clone(long[] array) {
294 if (array == null) {
295 return null;
296 }
297 return (long[]) array.clone();
298 }
299
300 /**
301 * <p>Clones an array returning a typecast result and handling
302 * <code>null</code>.</p>
303 *
304 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
305 *
306 * @param array the array to clone, may be <code>null</code>
307 * @return the cloned array, <code>null</code> if <code>null</code> input
308 */
309 public static int[] clone(int[] array) {
310 if (array == null) {
311 return null;
312 }
313 return (int[]) array.clone();
314 }
315
316 /**
317 * <p>Clones an array returning a typecast result and handling
318 * <code>null</code>.</p>
319 *
320 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
321 *
322 * @param array the array to clone, may be <code>null</code>
323 * @return the cloned array, <code>null</code> if <code>null</code> input
324 */
325 public static short[] clone(short[] array) {
326 if (array == null) {
327 return null;
328 }
329 return (short[]) array.clone();
330 }
331
332 /**
333 * <p>Clones an array returning a typecast result and handling
334 * <code>null</code>.</p>
335 *
336 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
337 *
338 * @param array the array to clone, may be <code>null</code>
339 * @return the cloned array, <code>null</code> if <code>null</code> input
340 */
341 public static char[] clone(char[] array) {
342 if (array == null) {
343 return null;
344 }
345 return (char[]) array.clone();
346 }
347
348 /**
349 * <p>Clones an array returning a typecast result and handling
350 * <code>null</code>.</p>
351 *
352 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
353 *
354 * @param array the array to clone, may be <code>null</code>
355 * @return the cloned array, <code>null</code> if <code>null</code> input
356 */
357 public static byte[] clone(byte[] array) {
358 if (array == null) {
359 return null;
360 }
361 return (byte[]) array.clone();
362 }
363
364 /**
365 * <p>Clones an array returning a typecast result and handling
366 * <code>null</code>.</p>
367 *
368 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
369 *
370 * @param array the array to clone, may be <code>null</code>
371 * @return the cloned array, <code>null</code> if <code>null</code> input
372 */
373 public static double[] clone(double[] array) {
374 if (array == null) {
375 return null;
376 }
377 return (double[]) array.clone();
378 }
379
380 /**
381 * <p>Clones an array returning a typecast result and handling
382 * <code>null</code>.</p>
383 *
384 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
385 *
386 * @param array the array to clone, may be <code>null</code>
387 * @return the cloned array, <code>null</code> if <code>null</code> input
388 */
389 public static float[] clone(float[] array) {
390 if (array == null) {
391 return null;
392 }
393 return (float[]) array.clone();
394 }
395
396 /**
397 * <p>Clones an array returning a typecast result and handling
398 * <code>null</code>.</p>
399 *
400 * <p>This method returns <code>null</code> for a <code>null</code> input array.</p>
401 *
402 * @param array the array to clone, may be <code>null</code>
403 * @return the cloned array, <code>null</code> if <code>null</code> input
404 */
405 public static boolean[] clone(boolean[] array) {
406 if (array == null) {
407 return null;
408 }
409 return (boolean[]) array.clone();
410 }
411
412 // Subarrays
413 //-----------------------------------------------------------------------
414 /**
415 * <p>Produces a new array containing the elements between
416 * the start and end indices.</p>
417 *
418 * <p>The start index is inclusive, the end index exclusive.
419 * Null array input produces null output.</p>
420 *
421 * <p>The component type of the subarray is always the same as
422 * that of the input array. Thus, if the input is an array of type
423 * <code>Date</code>, the following usage is envisaged:</p>
424 *
425 * <pre>
426 * Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
427 * </pre>
428 *
429 * @param array the array
430 * @param startIndexInclusive the starting index. Undervalue (<0)
431 * is promoted to 0, overvalue (>array.length) results
432 * in an empty array.
433 * @param endIndexExclusive elements up to endIndex-1 are present in the
434 * returned subarray. Undervalue (< startIndex) produces
435 * empty array, overvalue (>array.length) is demoted to
436 * array length.
437 * @return a new array containing the elements between
438 * the start and end indices.
439 * @since 2.1
440 */
441 public static Object[] subarray(Object[] array, int startIndexInclusive, int endIndexExclusive) {
442 if (array == null) {
443 return null;
444 }
445 if (startIndexInclusive < 0) {
446 startIndexInclusive = 0;
447 }
448 if (endIndexExclusive > array.length) {
449 endIndexExclusive = array.length;
450 }
451 int newSize = endIndexExclusive - startIndexInclusive;
452 Class type = array.getClass().getComponentType();
453 if (newSize <= 0) {
454 return (Object[]) Array.newInstance(type, 0);
455 }
456 Object[] subarray = (Object[]) Array.newInstance(type, newSize);
457 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
458 return subarray;
459 }
460
461 /**
462 * <p>Produces a new <code>long</code> array containing the elements
463 * between the start and end indices.</p>
464 *
465 * <p>The start index is inclusive, the end index exclusive.
466 * Null array input produces null output.</p>
467 *
468 * @param array the array
469 * @param startIndexInclusive the starting index. Undervalue (<0)
470 * is promoted to 0, overvalue (>array.length) results
471 * in an empty array.
472 * @param endIndexExclusive elements up to endIndex-1 are present in the
473 * returned subarray. Undervalue (< startIndex) produces
474 * empty array, overvalue (>array.length) is demoted to
475 * array length.
476 * @return a new array containing the elements between
477 * the start and end indices.
478 * @since 2.1
479 */
480 public static long[] subarray(long[] array, int startIndexInclusive, int endIndexExclusive) {
481 if (array == null) {
482 return null;
483 }
484 if (startIndexInclusive < 0) {
485 startIndexInclusive = 0;
486 }
487 if (endIndexExclusive > array.length) {
488 endIndexExclusive = array.length;
489 }
490 int newSize = endIndexExclusive - startIndexInclusive;
491 if (newSize <= 0) {
492 return EMPTY_LONG_ARRAY;
493 }
494
495 long[] subarray = new long[newSize];
496 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
497 return subarray;
498 }
499
500 /**
501 * <p>Produces a new <code>int</code> array containing the elements
502 * between the start and end indices.</p>
503 *
504 * <p>The start index is inclusive, the end index exclusive.
505 * Null array input produces null output.</p>
506 *
507 * @param array the array
508 * @param startIndexInclusive the starting index. Undervalue (<0)
509 * is promoted to 0, overvalue (>array.length) results
510 * in an empty array.
511 * @param endIndexExclusive elements up to endIndex-1 are present in the
512 * returned subarray. Undervalue (< startIndex) produces
513 * empty array, overvalue (>array.length) is demoted to
514 * array length.
515 * @return a new array containing the elements between
516 * the start and end indices.
517 * @since 2.1
518 */
519 public static int[] subarray(int[] array, int startIndexInclusive, int endIndexExclusive) {
520 if (array == null) {
521 return null;
522 }
523 if (startIndexInclusive < 0) {
524 startIndexInclusive = 0;
525 }
526 if (endIndexExclusive > array.length) {
527 endIndexExclusive = array.length;
528 }
529 int newSize = endIndexExclusive - startIndexInclusive;
530 if (newSize <= 0) {
531 return EMPTY_INT_ARRAY;
532 }
533
534 int[] subarray = new int[newSize];
535 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
536 return subarray;
537 }
538
539 /**
540 * <p>Produces a new <code>short</code> array containing the elements
541 * between the start and end indices.</p>
542 *
543 * <p>The start index is inclusive, the end index exclusive.
544 * Null array input produces null output.</p>
545 *
546 * @param array the array
547 * @param startIndexInclusive the starting index. Undervalue (<0)
548 * is promoted to 0, overvalue (>array.length) results
549 * in an empty array.
550 * @param endIndexExclusive elements up to endIndex-1 are present in the
551 * returned subarray. Undervalue (< startIndex) produces
552 * empty array, overvalue (>array.length) is demoted to
553 * array length.
554 * @return a new array containing the elements between
555 * the start and end indices.
556 * @since 2.1
557 */
558 public static short[] subarray(short[] array, int startIndexInclusive, int endIndexExclusive) {
559 if (array == null) {
560 return null;
561 }
562 if (startIndexInclusive < 0) {
563 startIndexInclusive = 0;
564 }
565 if (endIndexExclusive > array.length) {
566 endIndexExclusive = array.length;
567 }
568 int newSize = endIndexExclusive - startIndexInclusive;
569 if (newSize <= 0) {
570 return EMPTY_SHORT_ARRAY;
571 }
572
573 short[] subarray = new short[newSize];
574 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
575 return subarray;
576 }
577
578 /**
579 * <p>Produces a new <code>char</code> array containing the elements
580 * between the start and end indices.</p>
581 *
582 * <p>The start index is inclusive, the end index exclusive.
583 * Null array input produces null output.</p>
584 *
585 * @param array the array
586 * @param startIndexInclusive the starting index. Undervalue (<0)
587 * is promoted to 0, overvalue (>array.length) results
588 * in an empty array.
589 * @param endIndexExclusive elements up to endIndex-1 are present in the
590 * returned subarray. Undervalue (< startIndex) produces
591 * empty array, overvalue (>array.length) is demoted to
592 * array length.
593 * @return a new array containing the elements between
594 * the start and end indices.
595 * @since 2.1
596 */
597 public static char[] subarray(char[] array, int startIndexInclusive, int endIndexExclusive) {
598 if (array == null) {
599 return null;
600 }
601 if (startIndexInclusive < 0) {
602 startIndexInclusive = 0;
603 }
604 if (endIndexExclusive > array.length) {
605 endIndexExclusive = array.length;
606 }
607 int newSize = endIndexExclusive - startIndexInclusive;
608 if (newSize <= 0) {
609 return EMPTY_CHAR_ARRAY;
610 }
611
612 char[] subarray = new char[newSize];
613 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
614 return subarray;
615 }
616
617 /**
618 * <p>Produces a new <code>byte</code> array containing the elements
619 * between the start and end indices.</p>
620 *
621 * <p>The start index is inclusive, the end index exclusive.
622 * Null array input produces null output.</p>
623 *
624 * @param array the array
625 * @param startIndexInclusive the starting index. Undervalue (<0)
626 * is promoted to 0, overvalue (>array.length) results
627 * in an empty array.
628 * @param endIndexExclusive elements up to endIndex-1 are present in the
629 * returned subarray. Undervalue (< startIndex) produces
630 * empty array, overvalue (>array.length) is demoted to
631 * array length.
632 * @return a new array containing the elements between
633 * the start and end indices.
634 * @since 2.1
635 */
636 public static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) {
637 if (array == null) {
638 return null;
639 }
640 if (startIndexInclusive < 0) {
641 startIndexInclusive = 0;
642 }
643 if (endIndexExclusive > array.length) {
644 endIndexExclusive = array.length;
645 }
646 int newSize = endIndexExclusive - startIndexInclusive;
647 if (newSize <= 0) {
648 return EMPTY_BYTE_ARRAY;
649 }
650
651 byte[] subarray = new byte[newSize];
652 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
653 return subarray;
654 }
655
656 /**
657 * <p>Produces a new <code>double</code> array containing the elements
658 * between the start and end indices.</p>
659 *
660 * <p>The start index is inclusive, the end index exclusive.
661 * Null array input produces null output.</p>
662 *
663 * @param array the array
664 * @param startIndexInclusive the starting index. Undervalue (<0)
665 * is promoted to 0, overvalue (>array.length) results
666 * in an empty array.
667 * @param endIndexExclusive elements up to endIndex-1 are present in the
668 * returned subarray. Undervalue (< startIndex) produces
669 * empty array, overvalue (>array.length) is demoted to
670 * array length.
671 * @return a new array containing the elements between
672 * the start and end indices.
673 * @since 2.1
674 */
675 public static double[] subarray(double[] array, int startIndexInclusive, int endIndexExclusive) {
676 if (array == null) {
677 return null;
678 }
679 if (startIndexInclusive < 0) {
680 startIndexInclusive = 0;
681 }
682 if (endIndexExclusive > array.length) {
683 endIndexExclusive = array.length;
684 }
685 int newSize = endIndexExclusive - startIndexInclusive;
686 if (newSize <= 0) {
687 return EMPTY_DOUBLE_ARRAY;
688 }
689
690 double[] subarray = new double[newSize];
691 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
692 return subarray;
693 }
694
695 /**
696 * <p>Produces a new <code>float</code> array containing the elements
697 * between the start and end indices.</p>
698 *
699 * <p>The start index is inclusive, the end index exclusive.
700 * Null array input produces null output.</p>
701 *
702 * @param array the array
703 * @param startIndexInclusive the starting index. Undervalue (<0)
704 * is promoted to 0, overvalue (>array.length) results
705 * in an empty array.
706 * @param endIndexExclusive elements up to endIndex-1 are present in the
707 * returned subarray. Undervalue (< startIndex) produces
708 * empty array, overvalue (>array.length) is demoted to
709 * array length.
710 * @return a new array containing the elements between
711 * the start and end indices.
712 * @since 2.1
713 */
714 public static float[] subarray(float[] array, int startIndexInclusive, int endIndexExclusive) {
715 if (array == null) {
716 return null;
717 }
718 if (startIndexInclusive < 0) {
719 startIndexInclusive = 0;
720 }
721 if (endIndexExclusive > array.length) {
722 endIndexExclusive = array.length;
723 }
724 int newSize = endIndexExclusive - startIndexInclusive;
725 if (newSize <= 0) {
726 return EMPTY_FLOAT_ARRAY;
727 }
728
729 float[] subarray = new float[newSize];
730 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
731 return subarray;
732 }
733
734 /**
735 * <p>Produces a new <code>boolean</code> array containing the elements
736 * between the start and end indices.</p>
737 *
738 * <p>The start index is inclusive, the end index exclusive.
739 * Null array input produces null output.</p>
740 *
741 * @param array the array
742 * @param startIndexInclusive the starting index. Undervalue (<0)
743 * is promoted to 0, overvalue (>array.length) results
744 * in an empty array.
745 * @param endIndexExclusive elements up to endIndex-1 are present in the
746 * returned subarray. Undervalue (< startIndex) produces
747 * empty array, overvalue (>array.length) is demoted to
748 * array length.
749 * @return a new array containing the elements between
750 * the start and end indices.
751 * @since 2.1
752 */
753 public static boolean[] subarray(boolean[] array, int startIndexInclusive, int endIndexExclusive) {
754 if (array == null) {
755 return null;
756 }
757 if (startIndexInclusive < 0) {
758 startIndexInclusive = 0;
759 }
760 if (endIndexExclusive > array.length) {
761 endIndexExclusive = array.length;
762 }
763 int newSize = endIndexExclusive - startIndexInclusive;
764 if (newSize <= 0) {
765 return EMPTY_BOOLEAN_ARRAY;
766 }
767
768 boolean[] subarray = new boolean[newSize];
769 System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
770 return subarray;
771 }
772
773 // Is same length
774 //-----------------------------------------------------------------------
775 /**
776 * <p>Checks whether two arrays are the same length, treating
777 * <code>null</code> arrays as length <code>0</code>.
778 *
779 * <p>Any multi-dimensional aspects of the arrays are ignored.</p>
780 *
781 * @param array1 the first array, may be <code>null</code>
782 * @param array2 the second array, may be <code>null</code>
783 * @return <code>true</code> if length of arrays matches, treating
784 * <code>null</code> as an empty array
785 */
786 public static boolean isSameLength(Object[] array1, Object[] array2) {
787 if ((array1 == null && array2 != null && array2.length > 0) ||
788 (array2 == null && array1 != null && array1.length > 0) ||
789 (array1 != null && array2 != null && array1.length != array2.length)) {
790 return false;
791 }
792 return true;
793 }
794
795 /**
796 * <p>Checks whether two arrays are the same length, treating
797 * <code>null</code> arrays as length <code>0</code>.</p>
798 *
799 * @param array1 the first array, may be <code>null</code>
800 * @param array2 the second array, may be <code>null</code>
801 * @return <code>true</code> if length of arrays matches, treating
802 * <code>null</code> as an empty array
803 */
804 public static boolean isSameLength(long[] array1, long[] array2) {
805 if ((array1 == null && array2 != null && array2.length > 0) ||
806 (array2 == null && array1 != null && array1.length > 0) ||
807 (array1 != null && array2 != null && array1.length != array2.length)) {
808 return false;
809 }
810 return true;
811 }
812
813 /**
814 * <p>Checks whether two arrays are the same length, treating
815 * <code>null</code> arrays as length <code>0</code>.</p>
816 *
817 * @param array1 the first array, may be <code>null</code>
818 * @param array2 the second array, may be <code>null</code>
819 * @return <code>true</code> if length of arrays matches, treating
820 * <code>null</code> as an empty array
821 */
822 public static boolean isSameLength(int[] array1, int[] array2) {
823 if ((array1 == null && array2 != null && array2.length > 0) ||
824 (array2 == null && array1 != null && array1.length > 0) ||
825 (array1 != null && array2 != null && array1.length != array2.length)) {
826 return false;
827 }
828 return true;
829 }
830
831 /**
832 * <p>Checks whether two arrays are the same length, treating
833 * <code>null</code> arrays as length <code>0</code>.</p>
834 *
835 * @param array1 the first array, may be <code>null</code>
836 * @param array2 the second array, may be <code>null</code>
837 * @return <code>true</code> if length of arrays matches, treating
838 * <code>null</code> as an empty array
839 */
840 public static boolean isSameLength(short[] array1, short[] array2) {
841 if ((array1 == null && array2 != null && array2.length > 0) ||
842 (array2 == null && array1 != null && array1.length > 0) ||
843 (array1 != null && array2 != null && array1.length != array2.length)) {
844 return false;
845 }
846 return true;
847 }
848
849 /**
850 * <p>Checks whether two arrays are the same length, treating
851 * <code>null</code> arrays as length <code>0</code>.</p>
852 *
853 * @param array1 the first array, may be <code>null</code>
854 * @param array2 the second array, may be <code>null</code>
855 * @return <code>true</code> if length of arrays matches, treating
856 * <code>null</code> as an empty array
857 */
858 public static boolean isSameLength(char[] array1, char[] array2) {
859 if ((array1 == null && array2 != null && array2.length > 0) ||
860 (array2 == null && array1 != null && array1.length > 0) ||
861 (array1 != null && array2 != null && array1.length != array2.length)) {
862 return false;
863 }
864 return true;
865 }
866
867 /**
868 * <p>Checks whether two arrays are the same length, treating
869 * <code>null</code> arrays as length <code>0</code>.</p>
870 *
871 * @param array1 the first array, may be <code>null</code>
872 * @param array2 the second array, may be <code>null</code>
873 * @return <code>true</code> if length of arrays matches, treating
874 * <code>null</code> as an empty array
875 */
876 public static boolean isSameLength(byte[] array1, byte[] array2) {
877 if ((array1 == null && array2 != null && array2.length > 0) ||
878 (array2 == null && array1 != null && array1.length > 0) ||
879 (array1 != null && array2 != null && array1.length != array2.length)) {
880 return false;
881 }
882 return true;
883 }
884
885 /**
886 * <p>Checks whether two arrays are the same length, treating
887 * <code>null</code> arrays as length <code>0</code>.</p>
888 *
889 * @param array1 the first array, may be <code>null</code>
890 * @param array2 the second array, may be <code>null</code>
891 * @return <code>true</code> if length of arrays matches, treating
892 * <code>null</code> as an empty array
893 */
894 public static boolean isSameLength(double[] array1, double[] array2) {
895 if ((array1 == null && array2 != null && array2.length > 0) ||
896 (array2 == null && array1 != null && array1.length > 0) ||
897 (array1 != null && array2 != null && array1.length != array2.length)) {
898 return false;
899 }
900 return true;
901 }
902
903 /**
904 * <p>Checks whether two arrays are the same length, treating
905 * <code>null</code> arrays as length <code>0</code>.</p>
906 *
907 * @param array1 the first array, may be <code>null</code>
908 * @param array2 the second array, may be <code>null</code>
909 * @return <code>true</code> if length of arrays matches, treating
910 * <code>null</code> as an empty array
911 */
912 public static boolean isSameLength(float[] array1, float[] array2) {
913 if ((array1 == null && array2 != null && array2.length > 0) ||
914 (array2 == null && array1 != null && array1.length > 0) ||
915 (array1 != null && array2 != null && array1.length != array2.length)) {
916 return false;
917 }
918 return true;
919 }
920
921 /**
922 * <p>Checks whether two arrays are the same length, treating
923 * <code>null</code> arrays as length <code>0</code>.</p>
924 *
925 * @param array1 the first array, may be <code>null</code>
926 * @param array2 the second array, may be <code>null</code>
927 * @return <code>true</code> if length of arrays matches, treating
928 * <code>null</code> as an empty array
929 */
930 public static boolean isSameLength(boolean[] array1, boolean[] array2) {
931 if ((array1 == null && array2 != null && array2.length > 0) ||
932 (array2 == null && array1 != null && array1.length > 0) ||
933 (array1 != null && array2 != null && array1.length != array2.length)) {
934 return false;
935 }
936 return true;
937 }
938
939 //-----------------------------------------------------------------------
940 /**
941 * <p>Returns the length of the specified array.
942 * This method can deal with <code>Object</code> arrays and with primitive arrays.</p>
943 *
944 * <p>If the input array is <code>null</code>, <code>0</code> is returned.</p>
945 *
946 * <pre>
947 * ArrayUtils.getLength(null) = 0
948 * ArrayUtils.getLength([]) = 0
949 * ArrayUtils.getLength([null]) = 1
950 * ArrayUtils.getLength([true, false]) = 2
951 * ArrayUtils.getLength([1, 2, 3]) = 3
952 * ArrayUtils.getLength(["a", "b", "c"]) = 3
953 * </pre>
954 *
955 * @param array the array to retrieve the length from, may be null
956 * @return The length of the array, or <code>0</code> if the array is <code>null</code>
957 * @throws IllegalArgumentException if the object arguement is not an array.
958 * @since 2.1
959 */
960 public static int getLength(Object array) {
961 if (array == null) {
962 return 0;
963 }
964 return Array.getLength(array);
965 }
966
967 /**
968 * <p>Checks whether two arrays are the same type taking into account
969 * multi-dimensional arrays.</p>
970 *
971 * @param array1 the first array, must not be <code>null</code>
972 * @param array2 the second array, must not be <code>null</code>
973 * @return <code>true</code> if type of arrays matches
974 * @throws IllegalArgumentException if either array is <code>null</code>
975 */
976 public static boolean isSameType(Object array1, Object array2) {
977 if (array1 == null || array2 == null) {
978 throw new IllegalArgumentException("The Array must not be null");
979 }
980 return array1.getClass().getName().equals(array2.getClass().getName());
981 }
982
983 // Reverse
984 //-----------------------------------------------------------------------
985 /**
986 * <p>Reverses the order of the given array.</p>
987 *
988 * <p>There is no special handling for multi-dimensional arrays.</p>
989 *
990 * <p>This method does nothing for a <code>null</code> input array.</p>
991 *
992 * @param array the array to reverse, may be <code>null</code>
993 */
994 public static void reverse(Object[] array) {
995 if (array == null) {
996 return;
997 }
998 int i = 0;
999 int j = array.length - 1;
1000 Object tmp;
1001 while (j > i) {
1002 tmp = array[j];
1003 array[j] = array[i];
1004 array[i] = tmp;
1005 j--;
1006 i++;
1007 }
1008 }
1009
1010 /**
1011 * <p>Reverses the order of the given array.</p>
1012 *
1013 * <p>This method does nothing for a <code>null</code> input array.</p>
1014 *
1015 * @param array the array to reverse, may be <code>null</code>
1016 */
1017 public static void reverse(long[] array) {
1018 if (array == null) {
1019 return;
1020 }
1021 int i = 0;
1022 int j = array.length - 1;
1023 long tmp;
1024 while (j > i) {
1025 tmp = array[j];
1026 array[j] = array[i];
1027 array[i] = tmp;
1028 j--;
1029 i++;
1030 }
1031 }
1032
1033 /**
1034 * <p>Reverses the order of the given array.</p>
1035 *
1036 * <p>This method does nothing for a <code>null</code> input array.</p>
1037 *
1038 * @param array the array to reverse, may be <code>null</code>
1039 */
1040 public static void reverse(int[] array) {
1041 if (array == null) {
1042 return;
1043 }
1044 int i = 0;
1045 int j = array.length - 1;
1046 int tmp;
1047 while (j > i) {
1048 tmp = array[j];
1049 array[j] = array[i];
1050 array[i] = tmp;
1051 j--;
1052 i++;
1053 }
1054 }
1055
1056 /**
1057 * <p>Reverses the order of the given array.</p>
1058 *
1059 * <p>This method does nothing for a <code>null</code> input array.</p>
1060 *
1061 * @param array the array to reverse, may be <code>null</code>
1062 */
1063 public static void reverse(short[] array) {
1064 if (array == null) {
1065 return;
1066 }
1067 int i = 0;
1068 int j = array.length - 1;
1069 short tmp;
1070 while (j > i) {
1071 tmp = array[j];
1072 array[j] = array[i];
1073 array[i] = tmp;
1074 j--;
1075 i++;
1076 }
1077 }
1078
1079 /**
1080 * <p>Reverses the order of the given array.</p>
1081 *
1082 * <p>This method does nothing for a <code>null</code> input array.</p>
1083 *
1084 * @param array the array to reverse, may be <code>null</code>
1085 */
1086 public static void reverse(char[] array) {
1087 if (array == null) {
1088 return;
1089 }
1090 int i = 0;
1091 int j = array.length - 1;
1092 char tmp;
1093 while (j > i) {
1094 tmp = array[j];
1095 array[j] = array[i];
1096 array[i] = tmp;
1097 j--;
1098 i++;
1099 }
1100 }
1101
1102 /**
1103 * <p>Reverses the order of the given array.</p>
1104 *
1105 * <p>This method does nothing for a <code>null</code> input array.</p>
1106 *
1107 * @param array the array to reverse, may be <code>null</code>
1108 */
1109 public static void reverse(byte[] array) {
1110 if (array == null) {
1111 return;
1112 }
1113 int i = 0;
1114 int j = array.length - 1;
1115 byte tmp;
1116 while (j > i) {
1117 tmp = array[j];
1118 array[j] = array[i];
1119 array[i] = tmp;
1120 j--;
1121 i++;
1122 }
1123 }
1124
1125 /**
1126 * <p>Reverses the order of the given array.</p>
1127 *
1128 * <p>This method does nothing for a <code>null</code> input array.</p>
1129 *
1130 * @param array the array to reverse, may be <code>null</code>
1131 */
1132 public static void reverse(double[] array) {
1133 if (array == null) {
1134 return;
1135 }
1136 int i = 0;
1137 int j = array.length - 1;
1138 double tmp;
1139 while (j > i) {
1140 tmp = array[j];
1141 array[j] = array[i];
1142 array[i] = tmp;
1143 j--;
1144 i++;
1145 }
1146 }
1147
1148 /**