KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > lang > ArrayUtils


1 /*
2  * Copyright 2002-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.lang;
17
18 import java.lang.reflect.Array JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.apache.commons.lang.builder.EqualsBuilder;
23 import org.apache.commons.lang.builder.HashCodeBuilder;
24 import org.apache.commons.lang.builder.ToStringBuilder;
25 import org.apache.commons.lang.builder.ToStringStyle;
26
27 /**
28  * <p>Operations on arrays, primitive arrays (like <code>int[]</code>) and
29  * primitive wrapper arrays (like <code>Integer[]</code>).</p>
30  *
31  * <p>This class tries to handle <code>null</code> input gracefully.
32  * An exception will not be thrown for a <code>null</code>
33  * array input. However, an Object array that contains a <code>null</code>
34  * element may throw an exception. Each method documents its behaviour.</p>
35  *
36  * @author Stephen Colebourne
37  * @author Moritz Petersen
38  * @author <a HREF="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
39  * @author Nikolay Metchev
40  * @author Matthew Hawthorne
41  * @author Tim O'Brien
42  * @author Pete Gieser
43  * @author Gary Gregory
44  * @author <a HREF="mailto:equinus100@hotmail.com">Ashwin S</a>
45  * @author Maarten Coene
46  * @since 2.0
47  * @version $Id: ArrayUtils.java 161243 2005-04-14 04:30:28Z ggregory $
48  */

49 public class ArrayUtils {
50
51     /**
52      * An empty immutable <code>Object</code> array.
53      */

54     public static final Object JavaDoc[] EMPTY_OBJECT_ARRAY = new Object JavaDoc[0];
55     /**
56      * An empty immutable <code>Class</code> array.
57      */

58     public static final Class JavaDoc[] EMPTY_CLASS_ARRAY = new Class JavaDoc[0];
59     /**
60      * An empty immutable <code>String</code> array.
61      */

62     public static final String JavaDoc[] EMPTY_STRING_ARRAY = new String JavaDoc[0];
63     /**
64      * An empty immutable <code>long</code> array.
65      */

66     public static final long[] EMPTY_LONG_ARRAY = new long[0];
67     /**
68      * An empty immutable <code>Long</code> array.
69      */

70     public static final Long JavaDoc[] EMPTY_LONG_OBJECT_ARRAY = new Long JavaDoc[0];
71     /**
72      * An empty immutable <code>int</code> array.
73      */

74     public static final int[] EMPTY_INT_ARRAY = new int[0];
75     /**
76      * An empty immutable <code>Integer</code> array.
77      */

78     public static final Integer JavaDoc[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer JavaDoc[0];
79     /**
80      * An empty immutable <code>short</code> array.
81      */

82     public static final short[] EMPTY_SHORT_ARRAY = new short[0];
83     /**
84      * An empty immutable <code>Short</code> array.
85      */

86     public static final Short JavaDoc[] EMPTY_SHORT_OBJECT_ARRAY = new Short JavaDoc[0];
87     /**
88      * An empty immutable <code>byte</code> array.
89      */

90     public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
91     /**
92      * An empty immutable <code>Byte</code> array.
93      */

94     public static final Byte JavaDoc[] EMPTY_BYTE_OBJECT_ARRAY = new Byte JavaDoc[0];
95     /**
96      * An empty immutable <code>double</code> array.
97      */

98     public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
99     /**
100      * An empty immutable <code>Double</code> array.
101      */

102     public static final Double JavaDoc[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double JavaDoc[0];
103     /**
104      * An empty immutable <code>float</code> array.
105      */

106     public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
107     /**
108      * An empty immutable <code>Float</code> array.
109      */

110     public static final Float JavaDoc[] EMPTY_FLOAT_OBJECT_ARRAY = new Float JavaDoc[0];
111     /**
112      * An empty immutable <code>boolean</code> array.
113      */

114     public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
115     /**
116      * An empty immutable <code>Boolean</code> array.
117      */

118     public static final Boolean JavaDoc[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean JavaDoc[0];
119     /**
120      * An empty immutable <code>char</code> array.
121      */

122     public static final char[] EMPTY_CHAR_ARRAY = new char[0];
123     /**
124      * An empty immutable <code>Character</code> array.
125      */

126     public static final Character JavaDoc[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character JavaDoc[0];
127
128     /**
129      * <p>ArrayUtils instances should NOT be constructed in standard programming.
130      * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
131      *
132      * <p>This constructor is public to permit tools that require a JavaBean instance
133      * to operate.</p>
134      */

135     public ArrayUtils() {
136     }
137     
138     // Basic methods handling multi-dimensional arrays
139
//-----------------------------------------------------------------------
140
/**
141      * <p>Outputs an array as a String, treating <code>null</code> as an empty array.</p>
142      *
143      * <p>Multi-dimensional arrays are handled correctly, including
144      * multi-dimensional primitive arrays.</p>
145      *
146      * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
147      *
148      * @param array the array to get a toString for, may be <code>null</code>
149      * @return a String representation of the array, '{}' if null array input
150      */

151     public static String JavaDoc toString(Object JavaDoc array) {
152         return toString(array, "{}");
153     }
154
155     /**
156      * <p>Outputs an array as a String handling <code>null</code>s.</p>
157      *
158      * <p>Multi-dimensional arrays are handled correctly, including
159      * multi-dimensional primitive arrays.</p>
160      *
161      * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
162      *
163      * @param array the array to get a toString for, may be <code>null</code>
164      * @param stringIfNull the String to return if the array is <code>null</code>
165      * @return a String representation of the array
166      */

167     public static String JavaDoc toString(Object JavaDoc array, String JavaDoc stringIfNull) {
168         if (array == null) {
169             return stringIfNull;
170         }
171         return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
172     }
173
174     /**
175      * <p>Get a hashCode for an array handling multi-dimensional arrays correctly.</p>
176      *
177      * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
178      *
179      * @param array the array to get a hashCode for, may be <code>null</code>
180      * @return a hashCode for the array, zero if null array input
181      */

182     public static int hashCode(Object JavaDoc array) {
183         return new HashCodeBuilder().append(array).toHashCode();
184     }
185
186     /**
187      * <p>Compares two arrays, using equals(), handling multi-dimensional arrays
188      * correctly.</p>
189      *
190      * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
191      *
192      * @param array1 the left hand array to compare, may be <code>null</code>
193      * @param array2 the right hand array to compare, may be <code>null</code>
194      * @return <code>true</code> if the arrays are equal
195      */

196     public static boolean isEquals(Object JavaDoc array1, Object JavaDoc array2) {
197         return new EqualsBuilder().append(array1, array2).isEquals();
198     }
199
200     // To map
201
//-----------------------------------------------------------------------
202
/**
203      * <p>Converts the given array into a {@link java.util.Map}. Each element of the array
204      * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
205      * elements, where the first element is used as key and the second as
206      * value.</p>
207      *
208      * <p>This method can be used to initialize:</p>
209      * <pre>
210      * // Create a Map mapping colors.
211      * Map colorMap = MapUtils.toMap(new String[][] {{
212      * {"RED", "#FF0000"},
213      * {"GREEN", "#00FF00"},
214      * {"BLUE", "#0000FF"}});
215      * </pre>
216      *
217      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
218      *
219      * @param array an array whose elements are either a {@link java.util.Map.Entry} or
220      * an Array containing at least two elements, may be <code>null</code>
221      * @return a <code>Map</code> that was created from the array
222      * @throws IllegalArgumentException if one element of this Array is
223      * itself an Array containing less then two elements
224      * @throws IllegalArgumentException if the array contains elements other
225      * than {@link java.util.Map.Entry} and an Array
226      */

227     public static Map JavaDoc toMap(Object JavaDoc[] array) {
228         if (array == null) {
229             return null;
230         }
231         final Map JavaDoc map = new HashMap JavaDoc((int) (array.length * 1.5));
232         for (int i = 0; i < array.length; i++) {
233             Object JavaDoc object = array[i];
234             if (object instanceof Map.Entry JavaDoc) {
235                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) object;
236                 map.put(entry.getKey(), entry.getValue());
237             } else if (object instanceof Object JavaDoc[]) {
238                 Object JavaDoc[] entry = (Object JavaDoc[]) object;
239                 if (entry.length < 2) {
240                     throw new IllegalArgumentException JavaDoc("Array element " + i + ", '"
241                         + object
242                         + "', has a length less than 2");
243                 }
244                 map.put(entry[0], entry[1]);
245             } else {
246                 throw new IllegalArgumentException JavaDoc("Array element " + i + ", '"
247                         + object
248                         + "', is neither of type Map.Entry nor an Array");
249             }
250         }
251         return map;
252     }
253
254     // Clone
255
//-----------------------------------------------------------------------
256
/**
257      * <p>Shallow clones an array returning a typecast result and handling
258      * <code>null</code>.</p>
259      *
260      * <p>The objects in the array are not cloned, thus there is no special
261      * handling for multi-dimensional arrays.</p>
262      *
263      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
264      *
265      * @param array the array to shallow clone, may be <code>null</code>
266      * @return the cloned array, <code>null</code> if <code>null</code> input
267      */

268     public static Object JavaDoc[] clone(Object JavaDoc[] array) {
269         if (array == null) {
270             return null;
271         }
272         return (Object JavaDoc[]) array.clone();
273     }
274
275     /**
276      * <p>Clones an array returning a typecast result and handling
277      * <code>null</code>.</p>
278      *
279      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
280      *
281      * @param array the array to clone, may be <code>null</code>
282      * @return the cloned array, <code>null</code> if <code>null</code> input
283      */

284     public static long[] clone(long[] array) {
285         if (array == null) {
286             return null;
287         }
288         return (long[]) array.clone();
289     }
290
291     /**
292      * <p>Clones an array returning a typecast result and handling
293      * <code>null</code>.</p>
294      *
295      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
296      *
297      * @param array the array to clone, may be <code>null</code>
298      * @return the cloned array, <code>null</code> if <code>null</code> input
299      */

300     public static int[] clone(int[] array) {
301         if (array == null) {
302             return null;
303         }
304         return (int[]) array.clone();
305     }
306
307     /**
308      * <p>Clones an array returning a typecast result and handling
309      * <code>null</code>.</p>
310      *
311      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
312      *
313      * @param array the array to clone, may be <code>null</code>
314      * @return the cloned array, <code>null</code> if <code>null</code> input
315      */

316     public static short[] clone(short[] array) {
317         if (array == null) {
318             return null;
319         }
320         return (short[]) array.clone();
321     }
322
323     /**
324      * <p>Clones an array returning a typecast result and handling
325      * <code>null</code>.</p>
326      *
327      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
328      *
329      * @param array the array to clone, may be <code>null</code>
330      * @return the cloned array, <code>null</code> if <code>null</code> input
331      */

332     public static char[] clone(char[] array) {
333         if (array == null) {
334             return null;
335         }
336         return (char[]) array.clone();
337     }
338
339     /**
340      * <p>Clones an array returning a typecast result and handling
341      * <code>null</code>.</p>
342      *
343      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
344      *
345      * @param array the array to clone, may be <code>null</code>
346      * @return the cloned array, <code>null</code> if <code>null</code> input
347      */

348     public static byte[] clone(byte[] array) {
349         if (array == null) {
350             return null;
351         }
352         return (byte[]) array.clone();
353     }
354
355     /**
356      * <p>Clones an array returning a typecast result and handling
357      * <code>null</code>.</p>
358      *
359      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
360      *
361      * @param array the array to clone, may be <code>null</code>
362      * @return the cloned array, <code>null</code> if <code>null</code> input
363      */

364     public static double[] clone(double[] array) {
365         if (array == null) {
366             return null;
367         }
368         return (double[]) array.clone();
369     }
370
371     /**
372      * <p>Clones an array returning a typecast result and handling
373      * <code>null</code>.</p>
374      *
375      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
376      *
377      * @param array the array to clone, may be <code>null</code>
378      * @return the cloned array, <code>null</code> if <code>null</code> input
379      */

380     public static float[] clone(float[] array) {
381         if (array == null) {
382             return null;
383         }
384         return (float[]) array.clone();
385     }
386
387     /**
388      * <p>Clones an array returning a typecast result and handling
389      * <code>null</code>.</p>
390      *
391      * <p>This method returns <code>null</code> if <code>null</code> array input.</p>
392      *
393      * @param array the array to clone, may be <code>null</code>
394      * @return the cloned array, <code>null</code> if <code>null</code> input
395      */

396     public static boolean[] clone(boolean[] array) {
397         if (array == null) {
398             return null;
399         }
400         return (boolean[]) array.clone();
401     }
402
403     // Subarrays
404
//-----------------------------------------------------------------------
405
/**
406      * <p>Produces a new array containing the elements between
407      * the start and end indices.</p>
408      *
409      * <p>The start index is inclusive, the end index exclusive.
410      * Null array input produces null output.</p>
411      *
412      * <p>The component type of the subarray is always the same as
413      * that of the input array. Thus, if the input is an array of type
414      * <code>Date</code>, the following usage is envisaged:</p>
415      *
416      * <pre>
417      * Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
418      * </pre>
419      *
420      * @param array the array
421      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
422      * is promoted to 0, overvalue (&gt;array.length) results
423      * in an empty array.
424      * @param endIndexExclusive elements up to endIndex-1 are present in the
425      * returned subarray. Undervalue (&lt; startIndex) produces
426      * empty array, overvalue (&gt;array.length) is demoted to
427      * array length.
428      * @return a new array containing the elements between
429      * the start and end indices.
430      * @since 2.1
431      */

432     public static Object JavaDoc[] subarray(Object JavaDoc[] array, int startIndexInclusive, int endIndexExclusive) {
433         if (array == null) {
434             return null;
435         }
436         if (startIndexInclusive < 0) {
437             startIndexInclusive = 0;
438         }
439         if (endIndexExclusive > array.length) {
440             endIndexExclusive = array.length;
441         }
442         int newSize = endIndexExclusive - startIndexInclusive;
443         Class JavaDoc type = array.getClass().getComponentType();
444         if (newSize <= 0) {
445             return (Object JavaDoc[]) Array.newInstance(type, 0);
446         }
447         Object JavaDoc[] subarray = (Object JavaDoc[]) Array.newInstance(type, newSize);
448         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
449         return subarray;
450     }
451
452     /**
453      * <p>Produces a new <code>long</code> array containing the elements
454      * between the start and end indices.</p>
455      *
456      * <p>The start index is inclusive, the end index exclusive.
457      * Null array input produces null output.</p>
458      *
459      * @param array the array
460      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
461      * is promoted to 0, overvalue (&gt;array.length) results
462      * in an empty array.
463      * @param endIndexExclusive elements up to endIndex-1 are present in the
464      * returned subarray. Undervalue (&lt; startIndex) produces
465      * empty array, overvalue (&gt;array.length) is demoted to
466      * array length.
467      * @return a new array containing the elements between
468      * the start and end indices.
469      * @since 2.1
470      */

471     public static long[] subarray(long[] array, int startIndexInclusive, int endIndexExclusive) {
472         if (array == null) {
473             return null;
474         }
475         if (startIndexInclusive < 0) {
476             startIndexInclusive = 0;
477         }
478         if (endIndexExclusive > array.length) {
479             endIndexExclusive = array.length;
480         }
481         int newSize = endIndexExclusive - startIndexInclusive;
482         if (newSize <= 0) {
483             return EMPTY_LONG_ARRAY;
484         }
485
486         long[] subarray = new long[newSize];
487         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
488         return subarray;
489     }
490
491     /**
492      * <p>Produces a new <code>int</code> array containing the elements
493      * between the start and end indices.</p>
494      *
495      * <p>The start index is inclusive, the end index exclusive.
496      * Null array input produces null output.</p>
497      *
498      * @param array the array
499      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
500      * is promoted to 0, overvalue (&gt;array.length) results
501      * in an empty array.
502      * @param endIndexExclusive elements up to endIndex-1 are present in the
503      * returned subarray. Undervalue (&lt; startIndex) produces
504      * empty array, overvalue (&gt;array.length) is demoted to
505      * array length.
506      * @return a new array containing the elements between
507      * the start and end indices.
508      * @since 2.1
509      */

510     public static int[] subarray(int[] array, int startIndexInclusive, int endIndexExclusive) {
511         if (array == null) {
512             return null;
513         }
514         if (startIndexInclusive < 0) {
515             startIndexInclusive = 0;
516         }
517         if (endIndexExclusive > array.length) {
518             endIndexExclusive = array.length;
519         }
520         int newSize = endIndexExclusive - startIndexInclusive;
521         if (newSize <= 0) {
522             return EMPTY_INT_ARRAY;
523         }
524
525         int[] subarray = new int[newSize];
526         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
527         return subarray;
528     }
529
530     /**
531      * <p>Produces a new <code>short</code> array containing the elements
532      * between the start and end indices.</p>
533      *
534      * <p>The start index is inclusive, the end index exclusive.
535      * Null array input produces null output.</p>
536      *
537      * @param array the array
538      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
539      * is promoted to 0, overvalue (&gt;array.length) results
540      * in an empty array.
541      * @param endIndexExclusive elements up to endIndex-1 are present in the
542      * returned subarray. Undervalue (&lt; startIndex) produces
543      * empty array, overvalue (&gt;array.length) is demoted to
544      * array length.
545      * @return a new array containing the elements between
546      * the start and end indices.
547      * @since 2.1
548      */

549     public static short[] subarray(short[] array, int startIndexInclusive, int endIndexExclusive) {
550         if (array == null) {
551             return null;
552         }
553         if (startIndexInclusive < 0) {
554             startIndexInclusive = 0;
555         }
556         if (endIndexExclusive > array.length) {
557             endIndexExclusive = array.length;
558         }
559         int newSize = endIndexExclusive - startIndexInclusive;
560         if (newSize <= 0) {
561             return EMPTY_SHORT_ARRAY;
562         }
563
564         short[] subarray = new short[newSize];
565         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
566         return subarray;
567     }
568
569     /**
570      * <p>Produces a new <code>char</code> array containing the elements
571      * between the start and end indices.</p>
572      *
573      * <p>The start index is inclusive, the end index exclusive.
574      * Null array input produces null output.</p>
575      *
576      * @param array the array
577      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
578      * is promoted to 0, overvalue (&gt;array.length) results
579      * in an empty array.
580      * @param endIndexExclusive elements up to endIndex-1 are present in the
581      * returned subarray. Undervalue (&lt; startIndex) produces
582      * empty array, overvalue (&gt;array.length) is demoted to
583      * array length.
584      * @return a new array containing the elements between
585      * the start and end indices.
586      * @since 2.1
587      */

588     public static char[] subarray(char[] array, int startIndexInclusive, int endIndexExclusive) {
589         if (array == null) {
590             return null;
591         }
592         if (startIndexInclusive < 0) {
593             startIndexInclusive = 0;
594         }
595         if (endIndexExclusive > array.length) {
596             endIndexExclusive = array.length;
597         }
598         int newSize = endIndexExclusive - startIndexInclusive;
599         if (newSize <= 0) {
600             return EMPTY_CHAR_ARRAY;
601         }
602
603         char[] subarray = new char[newSize];
604         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
605         return subarray;
606     }
607
608     /**
609      * <p>Produces a new <code>byte</code> array containing the elements
610      * between the start and end indices.</p>
611      *
612      * <p>The start index is inclusive, the end index exclusive.
613      * Null array input produces null output.</p>
614      *
615      * @param array the array
616      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
617      * is promoted to 0, overvalue (&gt;array.length) results
618      * in an empty array.
619      * @param endIndexExclusive elements up to endIndex-1 are present in the
620      * returned subarray. Undervalue (&lt; startIndex) produces
621      * empty array, overvalue (&gt;array.length) is demoted to
622      * array length.
623      * @return a new array containing the elements between
624      * the start and end indices.
625      * @since 2.1
626      */

627     public static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) {
628         if (array == null) {
629             return null;
630         }
631         if (startIndexInclusive < 0) {
632             startIndexInclusive = 0;
633         }
634         if (endIndexExclusive > array.length) {
635             endIndexExclusive = array.length;
636         }
637         int newSize = endIndexExclusive - startIndexInclusive;
638         if (newSize <= 0) {
639             return EMPTY_BYTE_ARRAY;
640         }
641
642         byte[] subarray = new byte[newSize];
643         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
644         return subarray;
645     }
646
647     /**
648      * <p>Produces a new <code>double</code> array containing the elements
649      * between the start and end indices.</p>
650      *
651      * <p>The start index is inclusive, the end index exclusive.
652      * Null array input produces null output.</p>
653      *
654      * @param array the array
655      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
656      * is promoted to 0, overvalue (&gt;array.length) results
657      * in an empty array.
658      * @param endIndexExclusive elements up to endIndex-1 are present in the
659      * returned subarray. Undervalue (&lt; startIndex) produces
660      * empty array, overvalue (&gt;array.length) is demoted to
661      * array length.
662      * @return a new array containing the elements between
663      * the start and end indices.
664      * @since 2.1
665      */

666     public static double[] subarray(double[] array, int startIndexInclusive, int endIndexExclusive) {
667         if (array == null) {
668             return null;
669         }
670         if (startIndexInclusive < 0) {
671             startIndexInclusive = 0;
672         }
673         if (endIndexExclusive > array.length) {
674             endIndexExclusive = array.length;
675         }
676         int newSize = endIndexExclusive - startIndexInclusive;
677         if (newSize <= 0) {
678             return EMPTY_DOUBLE_ARRAY;
679         }
680
681         double[] subarray = new double[newSize];
682         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
683         return subarray;
684     }
685
686     /**
687      * <p>Produces a new <code>float</code> array containing the elements
688      * between the start and end indices.</p>
689      *
690      * <p>The start index is inclusive, the end index exclusive.
691      * Null array input produces null output.</p>
692      *
693      * @param array the array
694      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
695      * is promoted to 0, overvalue (&gt;array.length) results
696      * in an empty array.
697      * @param endIndexExclusive elements up to endIndex-1 are present in the
698      * returned subarray. Undervalue (&lt; startIndex) produces
699      * empty array, overvalue (&gt;array.length) is demoted to
700      * array length.
701      * @return a new array containing the elements between
702      * the start and end indices.
703      * @since 2.1
704      */

705     public static float[] subarray(float[] array, int startIndexInclusive, int endIndexExclusive) {
706         if (array == null) {
707             return null;
708         }
709         if (startIndexInclusive < 0) {
710             startIndexInclusive = 0;
711         }
712         if (endIndexExclusive > array.length) {
713             endIndexExclusive = array.length;
714         }
715         int newSize = endIndexExclusive - startIndexInclusive;
716         if (newSize <= 0) {
717             return EMPTY_FLOAT_ARRAY;
718         }
719
720         float[] subarray = new float[newSize];
721         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
722         return subarray;
723     }
724
725     /**
726      * <p>Produces a new <code>boolean</code> array containing the elements
727      * between the start and end indices.</p>
728      *
729      * <p>The start index is inclusive, the end index exclusive.
730      * Null array input produces null output.</p>
731      *
732      * @param array the array
733      * @param startIndexInclusive the starting index. Undervalue (&lt;0)
734      * is promoted to 0, overvalue (&gt;array.length) results
735      * in an empty array.
736      * @param endIndexExclusive elements up to endIndex-1 are present in the
737      * returned subarray. Undervalue (&lt; startIndex) produces
738      * empty array, overvalue (&gt;array.length) is demoted to
739      * array length.
740      * @return a new array containing the elements between
741      * the start and end indices.
742      * @since 2.1
743      */

744     public static boolean[] subarray(boolean[] array, int startIndexInclusive, int endIndexExclusive) {
745         if (array == null) {
746             return null;
747         }
748         if (startIndexInclusive < 0) {
749             startIndexInclusive = 0;
750         }
751         if (endIndexExclusive > array.length) {
752             endIndexExclusive = array.length;
753         }
754         int newSize = endIndexExclusive - startIndexInclusive;
755         if (newSize <= 0) {
756             return EMPTY_BOOLEAN_ARRAY;
757         }
758
759         boolean[] subarray = new boolean[newSize];
760         System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
761         return subarray;
762     }
763
764     // Is same length
765
//-----------------------------------------------------------------------
766
/**
767      * <p>Checks whether two arrays are the same length, treating
768      * <code>null</code> arrays as length <code>0</code>.
769      *
770      * <p>Any multi-dimensional aspects of the arrays are ignored.</p>
771      *
772      * @param array1 the first array, may be <code>null</code>
773      * @param array2 the second array, may be <code>null</code>
774      * @return <code>true</code> if length of arrays matches, treating
775      * <code>null</code> as an empty array
776      */

777     public static boolean isSameLength(Object JavaDoc[] array1, Object JavaDoc[] array2) {
778         if ((array1 == null && array2 != null && array2.length > 0) ||
779             (array2 == null && array1 != null && array1.length > 0) ||
780             (array1 != null && array2 != null && array1.length != array2.length)) {
781                 return false;
782         }
783         return true;
784     }
785
786     /**
787      * <p>Checks whether two arrays are the same length, treating
788      * <code>null</code> arrays as length <code>0</code>.</p>
789      *
790      * @param array1 the first array, may be <code>null</code>
791      * @param array2 the second array, may be <code>null</code>
792      * @return <code>true</code> if length of arrays matches, treating
793      * <code>null</code> as an empty array
794      */

795     public static boolean isSameLength(long[] array1, long[] array2) {
796         if ((array1 == null && array2 != null && array2.length > 0) ||
797             (array2 == null && array1 != null && array1.length > 0) ||
798             (array1 != null && array2 != null && array1.length != array2.length)) {
799                 return false;
800         }
801         return true;
802     }
803
804     /**
805      * <p>Checks whether two arrays are the same length, treating
806      * <code>null</code> arrays as length <code>0</code>.</p>
807      *
808      * @param array1 the first array, may be <code>null</code>
809      * @param array2 the second array, may be <code>null</code>
810      * @return <code>true</code> if length of arrays matches, treating
811      * <code>null</code> as an empty array
812      */

813     public static boolean isSameLength(int[] array1, int[] array2) {
814         if ((array1 == null && array2 != null && array2.length > 0) ||
815             (array2 == null && array1 != null && array1.length > 0) ||
816             (array1 != null && array2 != null && array1.length != array2.length)) {
817                 return false;
818         }
819         return true;
820     }
821
822     /**
823      * <p>Checks whether two arrays are the same length, treating
824      * <code>null</code> arrays as length <code>0</code>.</p>
825      *
826      * @param array1 the first array, may be <code>null</code>
827      * @param array2 the second array, may be <code>null</code>
828      * @return <code>true</code> if length of arrays matches, treating
829      * <code>null</code> as an empty array
830      */

831     public static boolean isSameLength(short[] array1, short[] array2) {
832         if ((array1 == null && array2 != null && array2.length > 0) ||
833             (array2 == null && array1 != null && array1.length > 0) ||
834             (array1 != null && array2 != null && array1.length != array2.length)) {
835                 return false;
836         }
837         return true;
838     }
839
840     /**
841      * <p>Checks whether two arrays are the same length, treating
842      * <code>null</code> arrays as length <code>0</code>.</p>
843      *
844      * @param array1 the first array, may be <code>null</code>
845      * @param array2 the second array, may be <code>null</code>
846      * @return <code>true</code> if length of arrays matches, treating
847      * <code>null</code> as an empty array
848      */

849     public static boolean isSameLength(char[] array1, char[] array2) {
850         if ((array1 == null && array2 != null && array2.length > 0) ||
851             (array2 == null && array1 != null && array1.length > 0) ||
852             (array1 != null && array2 != null && array1.length != array2.length)) {
853                 return false;
854         }
855         return true;
856     }
857
858     /**
859      * <p>Checks whether two arrays are the same length, treating
860      * <code>null</code> arrays as length <code>0</code>.</p>
861      *
862      * @param array1 the first array, may be <code>null</code>
863      * @param array2 the second array, may be <code>null</code>
864      * @return <code>true</code> if length of arrays matches, treating
865      * <code>null</code> as an empty array
866      */

867     public static boolean isSameLength(byte[] array1, byte[] array2) {
868         if ((array1 == null && array2 != null && array2.length > 0) ||
869             (array2 == null && array1 != null && array1.length > 0) ||
870             (array1 != null && array2 != null && array1.length != array2.length)) {
871                 return false;
872         }
873         return true;
874     }
875
876     /**
877  &