001    package com.softnetConsult.utils.collections;
002    
003    import java.util.HashSet;
004    import java.util.Iterator;
005    import java.util.Set;
006    
007    import com.softnetConsult.utils.exceptions.Bug;
008    
009    /**
010     * A collection of static utility functions for array processing.
011     * 
012     * <p style="font-size:smaller;">This product includes software developed by the
013     *    <strong>SoftNet-Consult Java Utility Library</strong> project and its contributors.<br />
014     *    (<a href="http://java-tools.sourceforge.net" target="_blank">http://java-tools.sourceforge.net</a>)<br />
015     *    Copyright (c) 2007-2008 SoftNet-Consult.<br />
016     *    Copyright (c) 2007-2008 G. Paperin.<br />
017     *    All rights reserved.
018     * </p>
019     * <p style="font-size:smaller;">File: ArrayTools.java<br />
020     *    Library API version: {@value com.softnetConsult.utils.APIProperties#apiVersion}<br />
021     *    Java compliance version: {@value com.softnetConsult.utils.APIProperties#javaComplianceVersion}
022     * </p>
023     * <p style="font-size:smaller;">Redistribution and use in source and binary forms, with or
024     *    without modification, are permitted provided that the following terms and conditions are met:
025     * </p>
026     * <p style="font-size:smaller;">1. Redistributions of source code must retain the above
027     *    acknowledgement of the SoftNet-Consult Java Utility Library project, the above copyright
028     *    notice, this list of conditions and the following disclaimer.<br />
029     *    2. Redistributions in binary form must reproduce the above acknowledgement of the
030     *    SoftNet-Consult Java Utility Library project, the above copyright notice, this list of
031     *    conditions and the following disclaimer in the documentation and/or other materials
032     *    provided with the distribution.<br />
033     *    3. All advertising materials mentioning features or use of this software or any derived
034     *    software must display the following acknowledgement:<br />
035     *    <em>This product includes software developed by the SoftNet-Consult Java Utility Library
036     *    project and its contributors.</em>
037     * </p>
038     * <p style="font-size:smaller;">THIS SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY
039     *    OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
040     *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL
041     *    THE AUTHORS, CONTRIBUTORS OR COPYRIGHT  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
042     *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING  FROM, OUT OF OR
043     *    IN CONNECTION WITH THE SOFTWARE OR THE USE OR  OTHER DEALINGS IN THE SOFTWARE.
044     * </p> 
045     * @author Greg Paperin (<a href="http://www.paperin.org" target="_blank">http://www.paperin.org</a>)
046     * @version {@value com.softnetConsult.utils.APIProperties#apiVersion}
047     *
048     */
049    public final class ArrayTools {
050    
051    /**
052     * Prevents instances of this class from being created
053     * as this class contains only static utility methods.
054     */
055    private ArrayTools() {}
056    
057    /**
058     * Default separator when converting arrays to Strings.
059     */
060    public static final String defaultArraySeparator = ", ";
061    
062    /**
063     * Opening bracket when converting arrays to Strings.
064     */
065    public static final String arrayOpen = "[";
066    
067    /**
068     * Closing bracket when converting arrays to Strings.
069     */
070    public static final String arrayClose = "]";
071    
072    /**
073     * A String representing a null.
074     */
075    public static final String nullName = "null";
076    
077    /**
078     * Creates an array iterator over the specified array.
079     * 
080     * @param <ET> Type of iteration objects.
081     * @param <AET> Array elements' type.
082     * @param array The array to iterate. 
083     * @return An {@code Iterator} over the specified array.
084     */
085    public static <ET, AET extends ET> ArrayIterator<ET> iterate(AET[] array) {         
086            return new ArrayIterator<ET>(array);
087    }
088    
089    /**
090     * Creates an array iterator over the specified array.
091     * 
092     * @param array The array to iterate. 
093     * @return An {@code Iterator} over the specified array.
094     */
095    public static ArrayIteratorBoolean iterate(boolean[] array) {           
096            return new ArrayIteratorBoolean(array);
097    }
098    
099    /**
100     * Creates an array iterator over the specified array.
101     * 
102     * @param array The array to iterate. 
103     * @return An {@code Iterator} over the specified array.
104     */
105    public static ArrayIteratorByte iterate(byte[] array) {         
106            return new ArrayIteratorByte(array);
107    }
108    
109    /**
110     * Creates an array iterator over the specified array.
111     * 
112     * @param array The array to iterate. 
113     * @return An {@code Iterator} over the specified array.
114     */
115    public static ArrayIteratorChar iterate(char[] array) {         
116            return new ArrayIteratorChar(array);
117    }
118    
119    /**
120     * Creates an array iterator over the specified array.
121     * 
122     * @param array The array to iterate. 
123     * @return An {@code Iterator} over the specified array.
124     */
125    public static ArrayIteratorShort iterate(short[] array) {               
126            return new ArrayIteratorShort(array);
127    }
128    
129    /**
130     * Creates an array iterator over the specified array.
131     * 
132     * @param array The array to iterate. 
133     * @return An {@code Iterator} over the specified array.
134     */
135    public static ArrayIteratorInt iterate(int[] array) {           
136            return new ArrayIteratorInt(array);
137    }
138    
139    /**
140     * Creates an array iterator over the specified array.
141     * 
142     * @param array The array to iterate. 
143     * @return An {@code Iterator} over the specified array.
144     */
145    public static ArrayIteratorLong iterate(long[] array) {         
146            return new ArrayIteratorLong(array);
147    }
148    
149    /**
150     * Creates an array iterator over the specified array.
151     * 
152     * @param array The array to iterate. 
153     * @return An {@code Iterator} over the specified array.
154     */
155    public static ArrayIteratorFloat iterate(float[] array) {               
156            return new ArrayIteratorFloat(array);
157    }
158    
159    /**
160     * Creates an array iterator over the specified array.
161     * 
162     * @param array The array to iterate. 
163     * @return An {@code Iterator} over the specified array.
164     */
165    public static ArrayIteratorDouble iterate(double[] array) {             
166            return new ArrayIteratorDouble(array);
167    }
168    
169    /**
170     * Creates an array iterator over the specified array.
171     * 
172     * @param array The array to iterate. 
173     * @return An {@code Iterator} over the specified array.
174     * @throws NullPointerException If the specified parameter is null.
175     * @throws NullPointerException If the specified parameter is not an array and not iterable.
176     */
177    public static Iterator<?> iterate(Object array) {         
178            
179            if (null == array)
180                    throw new NullPointerException("Cannot create an iterator on a null-array.");
181            
182            Class<?> ac = array.getClass();
183            if (!ac.isArray()) {
184                    if (array instanceof Iterable<?>)
185                            return ((Iterable<?>) array).iterator();
186                    else
187                            throw new IllegalArgumentException("Cannot iterate over a non-iterable object.");
188            }
189            
190            // "array" must be an array type:
191            
192            Class<?> ct = ac.getComponentType();
193            if (!ct.isPrimitive())
194                    return iterate((Object []) array);      
195            if (ct.equals(Boolean.TYPE))
196                    return iterate((boolean []) array);
197            if (ct.equals(Byte.TYPE))
198                    return iterate((byte []) array);
199            if (ct.equals(Character.TYPE))
200                    return iterate((char []) array);
201            if (ct.equals(Short.TYPE))
202                    return iterate((short []) array);
203            if (ct.equals(Integer.TYPE))
204                    return iterate((int []) array);
205            if (ct.equals(Long.TYPE))
206                    return iterate((long []) array);
207            if (ct.equals(Float.TYPE))
208                    return iterate((float []) array);
209            if (ct.equals(Double.TYPE))
210                    return iterate((double []) array);
211            
212            throw new Bug("Should never get to this line.");
213    }
214    
215    /**
216     * Converts the specified array to a string using {@code ", "} as delimeter.
217     * This is equivalent to {@code arrayToString(array, ", ")}.
218     *  
219     * @param <AET> Type of the array's elements. 
220     * @param array The array to converto to a string.
221     * @return A string representation of the specifoed array.
222     */
223    public static <AET> String arrayToString(AET[] array) {
224            return arrayToString(array, defaultArraySeparator);
225    }
226    
227    /**
228     * Converts the specified array to a string using the specified character as delimeter.
229     * This is equivalent to
230     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
231     * 
232     * @param <AET> Type of the array's elements. 
233     * @param array The array to converto to a string.
234     * @param listSeparator The values separator character.
235     * @return A string representation of the specifoed array.
236     */
237    public static <AET> String arrayToString(AET[] array, char listSeparator) {
238            return arrayToString(array, new String(new char[] {listSeparator}));
239    }
240    
241    /**
242     * Converts the specified array to a string using {@code '['} and {@code ']'} as
243     * start and end indicators, {@code "null"} as null element indicator and the
244     * specified {@code listSeparator}} as element delimeter. For instance,
245     * <code>arrayToString(new Integer[] {0, -5, null, 11}, "; ")</code> will create the
246     * string {@code "[0; -5; null, 11]"}.
247     *  
248     * @param <AET> Type of the array's elements. 
249     * @param array The array to convert to a string.
250     * @param listSeparator The values separator.
251     * @return A string representation of the specified array.
252     */
253    public static <AET> String arrayToString(AET[] array, String listSeparator) {
254            return arrayToString(array, listSeparator, null);
255    }
256    
257    /**
258     * This private method is used internally by {@link #arrayToString(Object[], String)} and
259     * has an additional parameter used to keep track or recursively processed arrays in order
260     * to avoid infinite recursion.
261     * 
262     * @param <AET> Type of the array's elements. 
263     * @param array The array to convert to a string.
264     * @param listSeparator The values separator.
265     * @param seenSubarrays Arrays already processed bythis recursion.
266     * @return A string representation of the specified array.
267     */
268    private static <AET> String arrayToString(AET[] array, String listSeparator, Set<Object> seenSubarrays) {
269            
270            if (null == array)
271                    return nullName;
272            
273            if (null == listSeparator)
274                    listSeparator = "";
275            
276            StringBuffer b = new StringBuffer();
277            b.append(arrayOpen);
278            for (int i = 0; i < array.length; i++) {
279                    
280                    if (0 < i)
281                            b.append(listSeparator);
282                    
283                    AET element = array[i];
284                    
285                    if (null == element) {
286                            b.append(nullName);
287                            continue;
288                    }
289                    
290                    Class<? extends AET> elementClass = element.getClass();           
291                    if (elementClass.isArray()) {
292                            
293                            if (null == seenSubarrays)
294                                    seenSubarrays = new HashSet<Object>();
295                            
296                            if (seenSubarrays.contains(element)) {
297                                    b.append(arrayOpen + "Recursed array of " + elementClass.getComponentType() + arrayClose);
298                                    
299                            } else {
300                                    seenSubarrays.add(element);
301                                    b.append(arrayToString(element, listSeparator, seenSubarrays));
302                                    seenSubarrays.remove(element);
303                            }
304                    
305                    } else {
306                            
307                            b.append(String.valueOf(element));
308                    }
309            }       
310            b.append(arrayClose);
311            
312            return b.toString();    
313    }
314    
315    /**
316     * Converts the specified array to a string using {@code ", "} as delimeter.
317     * If the specified parameter is not an array, a String representation of the
318     * parameter is returned. This is equivalent to {@code arrayToString(array, ", ")}.
319     *   
320     * @param array The array to converto to a string.
321     * @return A string representation of the specifoed array.
322     */
323    public static String arrayToString(Object array) {
324            return arrayToString(array, defaultArraySeparator);
325    }
326    
327    /**
328     * Converts the specified array to a string using the specified character as delimeter.
329     * If the specified parameter is not an array, a String representation of the
330     * parameter is returned. This is equivalent to
331     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
332     *  
333     * @param array The array to converto to a string.
334     * @param listSeparator The values separator character.
335     * @return A string representation of the specifoed array.
336     */
337    public static String arrayToString(Object array, char listSeparator) {
338            return arrayToString(array, new String(new char[] {listSeparator}));
339    }
340    
341    /**
342     * Converts the specified array to a string using {@code '['} and {@code ']'} as
343     * start and end indicators, {@code "null"} as null element indicator and the
344     * specified {@code listSeparator}} as element delimeter. For instance,
345     * <code>arrayToString(new Integer[] {0, -5, null, 11}, "; ")</code> will create the
346     * string {@code "[0; -5; null, 11]"}.
347     * If the specified parameter is not an array, a String representation of the
348     * parameter is returned. 
349     *  
350     * @param array The array to convert to a string.
351     * @param listSeparator The values separator.
352     * @return A string representation of the specifoed array.
353     */
354    public static String arrayToString(Object array, String listSeparator) {
355            return arrayToString(array, listSeparator, null);
356    }
357    
358    /**
359     * This private method is used internally by {@link #arrayToString(Object, String)} and
360     * has an additional parameter used to keep track or recursively processed arrays in order
361     * to avoid infinite recursion.
362     * 
363     * @param array The array to convert to a string.
364     * @param listSeparator The values separator.
365     * @param seenSubarrays Arrays already processed bythis recursion.
366     * @return A string representation of the specified array.
367     */
368    private static String arrayToString(Object array, String listSeparator, Set<Object> seenSubarrays) {
369            
370            if (null == array)
371                    return nullName;
372            
373            Class<?> ac = array.getClass();
374            if (!ac.isArray())
375                    return String.valueOf(array);
376            
377            Class<?> ct = ac.getComponentType();
378            if (!ct.isPrimitive())
379                    return arrayToString((Object []) array, listSeparator, seenSubarrays);  
380            if (ct.equals(Boolean.TYPE))
381                    return arrayToString((boolean []) array, listSeparator);
382            if (ct.equals(Byte.TYPE))
383                    return arrayToString((byte []) array, listSeparator);
384            if (ct.equals(Character.TYPE))
385                    return arrayToString((char []) array, listSeparator);
386            if (ct.equals(Short.TYPE))
387                    return arrayToString((short []) array, listSeparator);
388            if (ct.equals(Integer.TYPE))
389                    return arrayToString((int []) array, listSeparator);
390            if (ct.equals(Long.TYPE))
391                    return arrayToString((long []) array, listSeparator);
392            if (ct.equals(Float.TYPE))
393                    return arrayToString((float []) array, listSeparator);
394            if (ct.equals(Double.TYPE))
395                    return arrayToString((double []) array, listSeparator);
396            if (ct.equals(Void.TYPE))                       
397                    return arrayOpen + "Array of void" + arrayClose;
398            
399            throw new Bug("Should never get to this line.");
400    }
401    
402    /**
403     * Converts the specified array to a string using {@code ", "} as delimeter.
404     * This is equivalent to {@code arrayToString(array, ", ")}.
405     *  
406     * @param array The array to converto to a string.
407     * @return A string representation of the specifoed array.
408     */
409    public static String arrayToString(boolean[] array) {
410            return arrayToString(array, defaultArraySeparator);
411    }
412    
413    /**
414     * Converts the specified array to a string using the specified character as delimeter.
415     * This is equivalent to
416     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
417     *  
418     * @param array The array to converto to a string.
419     * @param listSeparator The values separator character.
420     * @return A string representation of the specifoed array.
421     */
422    public static String arrayToString(boolean[] array, char listSeparator) {
423            return arrayToString(array, new String(new char[] {listSeparator}));
424    }
425    
426    /**
427     * Converts the specified array to a string using {@code '['} and {@code ']'} as start
428     * and end indicators and the specified {@code listSeparator}} as element delimeter.
429     *  
430     * @param array The array to convert to a string.
431     * @param listSeparator The values separator.
432     * @return A string representation of the specified array.
433     */
434    public static String arrayToString(boolean[] array, String listSeparator) {
435            
436            if (null == array)
437                    return nullName;
438            
439            if (null == listSeparator)
440                    listSeparator = "";
441            
442            StringBuffer b = new StringBuffer();
443            b.append(arrayOpen);
444            for (int i = 0; i < array.length; i++) {             
445                    if (0 < i)
446                            b.append(listSeparator);                
447                    b.append(String.valueOf(array[i]));
448            }       
449            b.append(arrayClose);
450            
451            return b.toString();    
452    }
453    
454    /**
455     * Converts the specified array to a string using {@code ", "} as delimeter.
456     * This is equivalent to {@code arrayToString(array, ", ")}.
457     *  
458     * @param array The array to converto to a string.
459     * @return A string representation of the specifoed array.
460     */
461    public static String arrayToString(byte[] array) {
462            return arrayToString(array, defaultArraySeparator);
463    }
464    
465    /**
466     * Converts the specified array to a string using the specified character as delimeter.
467     * This is equivalent to
468     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
469     *  
470     * @param array The array to converto to a string.
471     * @param listSeparator The values separator character.
472     * @return A string representation of the specifoed array.
473     */
474    public static String arrayToString(byte[] array, char listSeparator) {
475            return arrayToString(array, new String(new char[] {listSeparator}));
476    }
477    
478    /**
479     * Converts the specified array to a string using {@code '['} and {@code ']'} as start
480     * and end indicators and the specified {@code listSeparator}} as element delimeter.
481     *  
482     * @param array The array to convert to a string.
483     * @param listSeparator The values separator.
484     * @return A string representation of the specified array.
485     */
486    public static String arrayToString(byte[] array, String listSeparator) {
487            
488            if (null == array)
489                    return nullName;
490            
491            if (null == listSeparator)
492                    listSeparator = "";
493            
494            StringBuffer b = new StringBuffer();
495            b.append(arrayOpen);
496            for (int i = 0; i < array.length; i++) {             
497                    if (0 < i)
498                            b.append(listSeparator);                
499                    b.append(String.valueOf(array[i]));
500            }       
501            b.append(arrayClose);
502            
503            return b.toString();    
504    }
505    
506    /**
507     * Converts the specified array to a string using {@code ", "} as delimeter.
508     * This is equivalent to {@code arrayToString(array, ", ")}.
509     *  
510     * @param array The array to converto to a string.
511     * @return A string representation of the specifoed array.
512     */
513    public static String arrayToString(char[] array) {
514            return arrayToString(array, defaultArraySeparator);
515    }
516    
517    /**
518     * Converts the specified array to a string using the specified character as delimeter.
519     * This is equivalent to
520     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
521     *  
522     * @param array The array to converto to a string.
523     * @param listSeparator The values separator character.
524     * @return A string representation of the specifoed array.
525     */
526    public static String arrayToString(char[] array, char listSeparator) {
527            return arrayToString(array, new String(new char[] {listSeparator}));
528    }
529    
530    /**
531     * Converts the specified array to a string using {@code '['} and {@code ']'} as start
532     * and end indicators and the specified {@code listSeparator}} as element delimeter.
533     *  
534     * @param array The array to convert to a string.
535     * @param listSeparator The values separator.
536     * @return A string representation of the specified array.
537     */
538    public static String arrayToString(char[] array, String listSeparator) {
539            
540            if (null == array)
541                    return nullName;
542            
543            if (null == listSeparator)
544                    listSeparator = "";
545            
546            StringBuffer b = new StringBuffer();
547            b.append(arrayOpen);
548            for (int i = 0; i < array.length; i++) {             
549                    if (0 < i)
550                            b.append(listSeparator);                
551                    b.append(String.valueOf(array[i]));
552            }       
553            b.append(arrayClose);
554            
555            return b.toString();    
556    }
557    
558    /**
559     * Converts the specified array to a string using {@code ", "} as delimeter.
560     * This is equivalent to {@code arrayToString(array, ", ")}.
561     *  
562     * @param array The array to converto to a string.
563     * @return A string representation of the specifoed array.
564     */
565    public static String arrayToString(short[] array) {
566            return arrayToString(array, defaultArraySeparator);
567    }
568    
569    /**
570     * Converts the specified array to a string using the specified character as delimeter.
571     * This is equivalent to
572     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
573     *  
574     * @param array The array to converto to a string.
575     * @param listSeparator The values separator character.
576     * @return A string representation of the specifoed array.
577     */
578    public static String arrayToString(short[] array, char listSeparator) {
579            return arrayToString(array, new String(new char[] {listSeparator}));
580    }
581    
582    /**
583     * Converts the specified array to a string using {@code '['} and {@code ']'} as start
584     * and end indicators and the specified {@code listSeparator}} as element delimeter.
585     *  
586     * @param array The array to convert to a string.
587     * @param listSeparator The values separator.
588     * @return A string representation of the specified array.
589     */
590    public static String arrayToString(short[] array, String listSeparator) {
591            
592            if (null == array)
593                    return nullName;
594            
595            if (null == listSeparator)
596                    listSeparator = "";
597            
598            StringBuffer b = new StringBuffer();
599            b.append(arrayOpen);
600            for (int i = 0; i < array.length; i++) {             
601                    if (0 < i)
602                            b.append(listSeparator);                
603                    b.append(String.valueOf(array[i]));
604            }       
605            b.append(arrayClose);
606            
607            return b.toString();    
608    }
609    
610    /**
611     * Converts the specified array to a string using {@code ", "} as delimeter.
612     * This is equivalent to {@code arrayToString(array, ", ")}.
613     *  
614     * @param array The array to converto to a string.
615     * @return A string representation of the specifoed array.
616     */
617    public static String arrayToString(int[] array) {
618            return arrayToString(array, defaultArraySeparator);
619    }
620    
621    /**
622     * Converts the specified array to a string using the specified character as delimeter.
623     * This is equivalent to
624     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
625     *  
626     * @param array The array to converto to a string.
627     * @param listSeparator The values separator character.
628     * @return A string representation of the specifoed array.
629     */
630    public static String arrayToString(int[] array, char listSeparator) {
631            return arrayToString(array, new String(new char[] {listSeparator}));
632    }
633    
634    /**
635     * Converts the specified array to a string using {@code '['} and {@code ']'} as start
636     * and end indicators and the specified {@code listSeparator}} as element delimeter.
637     *  
638     * @param array The array to convert to a string.
639     * @param listSeparator The values separator.
640     * @return A string representation of the specified array.
641     */
642    public static String arrayToString(int[] array, String listSeparator) {
643            
644            if (null == array)
645                    return nullName;
646            
647            if (null == listSeparator)
648                    listSeparator = "";
649            
650            StringBuffer b = new StringBuffer();
651            b.append(arrayOpen);
652            for (int i = 0; i < array.length; i++) {             
653                    if (0 < i)
654                            b.append(listSeparator);                
655                    b.append(String.valueOf(array[i]));
656            }       
657            b.append(arrayClose);
658            
659            return b.toString();    
660    }
661    
662    /**
663     * Converts the specified array to a string using {@code ", "} as delimeter.
664     * This is equivalent to {@code arrayToString(array, ", ")}.
665     *  
666     * @param array The array to converto to a string.
667     * @return A string representation of the specifoed array.
668     */
669    public static String arrayToString(long[] array) {
670            return arrayToString(array, defaultArraySeparator);
671    }
672    
673    /**
674     * Converts the specified array to a string using the specified character as delimeter.
675     * This is equivalent to
676     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
677     *  
678     * @param array The array to converto to a string.
679     * @param listSeparator The values separator character.
680     * @return A string representation of the specifoed array.
681     */
682    public static String arrayToString(long[] array, char listSeparator) {
683            return arrayToString(array, new String(new char[] {listSeparator}));
684    }
685    
686    /**
687     * Converts the specified array to a string using {@code '['} and {@code ']'} as start
688     * and end indicators and the specified {@code listSeparator}} as element delimeter.
689     *  
690     * @param array The array to convert to a string.
691     * @param listSeparator The values separator.
692     * @return A string representation of the specified array.
693     */
694    public static String arrayToString(long[] array, String listSeparator) {
695            
696            if (null == array)
697                    return nullName;
698            
699            if (null == listSeparator)
700                    listSeparator = "";
701            
702            StringBuffer b = new StringBuffer();
703            b.append(arrayOpen);
704            for (int i = 0; i < array.length; i++) {             
705                    if (0 < i)
706                            b.append(listSeparator);                
707                    b.append(String.valueOf(array[i]));
708            }       
709            b.append(arrayClose);
710            
711            return b.toString();    
712    }
713    
714    /**
715     * Converts the specified array to a string using {@code ", "} as delimeter.
716     * This is equivalent to {@code arrayToString(array, ", ")}.
717     *  
718     * @param array The array to converto to a string.
719     * @return A string representation of the specifoed array.
720     */
721    public static String arrayToString(float[] array) {
722            return arrayToString(array, defaultArraySeparator);
723    }
724    
725    /**
726     * Converts the specified array to a string using the specified character as delimeter.
727     * This is equivalent to
728     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
729     *  
730     * @param array The array to converto to a string.
731     * @param listSeparator The values separator character.
732     * @return A string representation of the specifoed array.
733     */
734    public static String arrayToString(float[] array, char listSeparator) {
735            return arrayToString(array, new String(new char[] {listSeparator}));
736    }
737    
738    /**
739     * Converts the specified array to a string using {@code '['} and {@code ']'} as start
740     * and end indicators and the specified {@code listSeparator}} as element delimeter.
741     *  
742     * @param array The array to convert to a string.
743     * @param listSeparator The values separator.
744     * @return A string representation of the specified array.
745     */
746    public static String arrayToString(float[] array, String listSeparator) {
747            
748            if (null == array)
749                    return nullName;
750            
751            if (null == listSeparator)
752                    listSeparator = "";
753            
754            StringBuffer b = new StringBuffer();
755            b.append(arrayOpen);
756            for (int i = 0; i < array.length; i++) {             
757                    if (0 < i)
758                            b.append(listSeparator);                
759                    b.append(String.valueOf(array[i]));
760            }       
761            b.append(arrayClose);
762            
763            return b.toString();    
764    }
765    
766    /**
767     * Converts the specified array to a string using {@code ", "} as delimeter.
768     * This is equivalent to {@code arrayToString(array, ", ")}.
769     *  
770     * @param array The array to converto to a string.
771     * @return A string representation of the specifoed array.
772     */
773    public static String arrayToString(double[] array) {
774            return arrayToString(array, defaultArraySeparator);
775    }
776    
777    /**
778     * Converts the specified array to a string using the specified character as delimeter.
779     * This is equivalent to
780     * <code>arrayToString(array, new String(new char[] {listSeparator}))</code>.
781     *  
782     * @param array The array to converto to a string.
783     * @param listSeparator The values separator character.
784     * @return A string representation of the specifoed array.
785     */
786    public static String arrayToString(double[] array, char listSeparator) {
787            return arrayToString(array, new String(new char[] {listSeparator}));
788    }
789    
790    /**
791     * Converts the specified array to a string using {@code '['} and {@code ']'} as start
792     * and end indicators and the specified {@code listSeparator}} as element delimeter.
793     *  
794     * @param array The array to convert to a string.
795     * @param listSeparator The values separator.
796     * @return A string representation of the specified array.
797     */
798    public static String arrayToString(double[] array, String listSeparator) {
799            
800            if (null == array)
801                    return nullName;
802            
803            if (null == listSeparator)
804                    listSeparator = "";
805            
806            StringBuffer b = new StringBuffer();
807            b.append(arrayOpen);
808            for (int i = 0; i < array.length; i++) {             
809                    if (0 < i)
810                            b.append(listSeparator);                
811                    b.append(String.valueOf(array[i]));
812            }       
813            b.append(arrayClose);
814            
815            return b.toString();    
816    }
817    
818    /**
819     * Converts an array of primitive {@code boolean} values to an array of {@code Boolean}
820     * objects wrapping the respective primitive values.
821     * 
822     * @param arr An array.
823     * @return A corresponding array of wrapper objects
824     * or {@code null} if the specified array is {@code null}.
825     */
826    public static Boolean[] toWrapperArray(boolean[] arr) { 
827            if (null == arr)
828                    return null;
829            Boolean[] wrapers = new Boolean[arr.length];
830            for (int i = 0; i < arr.length; i++)
831                    wrapers[i] = Boolean.valueOf(arr[i]);
832            return wrapers;
833    }
834    
835    /**
836     * Converts an array of primitive {@code byte} values to an array of {@code Byte}
837     * objects wrapping the respective primitive values.
838     * 
839     * @param arr An array.
840     * @return A corresponding array of wrapper objects
841     * or {@code null} if the specified array is {@code null}.
842     */
843    public static Byte[] toWrapperArray(byte[] arr) {       
844            if (null == arr)
845                    return null;
846            Byte[] wrapers = new Byte[arr.length];
847            for (int i = 0; i < arr.length; i++)
848                    wrapers[i] = Byte.valueOf(arr[i]);
849            return wrapers;
850    }
851    
852    /**
853     * Converts an array of primitive {@code char} values to an array of {@code Character}
854     * objects wrapping the respective primitive values.
855     * 
856     * @param arr An array.
857     * @return A corresponding array of wrapper objects
858     * or {@code null} if the specified array is {@code null}.
859     */
860    public static Character[] toWrapperArray(char[] arr) {  
861            if (null == arr)
862                    return null;
863            Character[] wrapers = new Character[arr.length];
864            for (int i = 0; i < arr.length; i++)
865                    wrapers[i] = Character.valueOf(arr[i]);
866            return wrapers;
867    }
868    
869    /**
870     * Converts an array of primitive {@code short} values to an array of {@code Short}
871     * objects wrapping the respective primitive values.
872     * 
873     * @param arr An array.
874     * @return A corresponding array of wrapper objects
875     * or {@code null} if the specified array is {@code null}.
876     */
877    public static Short[] toWrapperArray(short[] arr) {     
878            if (null == arr)
879                    return null;
880            Short[] wrapers = new Short[arr.length];
881            for (int i = 0; i < arr.length; i++)
882                    wrapers[i] = Short.valueOf(arr[i]);
883            return wrapers;
884    }
885    
886    /**
887     * Converts an array of primitive {@code int} values to an array of {@code Integer}
888     * objects wrapping the respective primitive values.
889     * 
890     * @param arr An array.
891     * @return A corresponding array of wrapper objects
892     * or {@code null} if the specified array is {@code null}.
893     */
894    public static Integer[] toWrapperArray(int[] arr) {     
895            if (null == arr)
896                    return null;
897            Integer[] wrapers = new Integer[arr.length];
898            for (int i = 0; i < arr.length; i++)
899                    wrapers[i] = Integer.valueOf(arr[i]);
900            return wrapers;
901    }
902    
903    /**
904     * Converts an array of primitive {@code long} values to an array of {@code Long}
905     * objects wrapping the respective primitive values.
906     * 
907     * @param arr An array.
908     * @return A corresponding array of wrapper objects
909     * or {@code null} if the specified array is {@code null}.
910     */
911    public static Long[] toWrapperArray(long[] arr) {       
912            if (null == arr)
913                    return null;
914            Long[] wrapers = new Long[arr.length];
915            for (int i = 0; i < arr.length; i++)
916                    wrapers[i] = Long.valueOf(arr[i]);
917            return wrapers;
918    }
919    
920    /**
921     * Converts an array of primitive {@code float} values to an array of {@code Float}
922     * objects wrapping the respective primitive values.
923     * 
924     * @param arr An array.
925     * @return A corresponding array of wrapper objects
926     * or {@code null} if the specified array is {@code null}.
927     */
928    public static Float[] toWrapperArray(float[] arr) {     
929            if (null == arr)
930                    return null;
931            Float[] wrapers = new Float[arr.length];
932            for (int i = 0; i < arr.length; i++)
933                    wrapers[i] = Float.valueOf(arr[i]);
934            return wrapers;
935    }
936    
937    /**
938     * Converts an array of primitive {@code double} values to an array of {@code Double}
939     * objects wrapping the respective primitive values.
940     * 
941     * @param arr An array.
942     * @return A corresponding array of wrapper objects
943     * or {@code null} if the specified array is {@code null}.
944     */
945    public static Double[] toWrapperArray(double[] arr) {   
946            if (null == arr)
947                    return null;
948            Double[] wrapers = new Double[arr.length];
949            for (int i = 0; i < arr.length; i++)
950                    wrapers[i] = Double.valueOf(arr[i]);
951            return wrapers;
952    }
953    
954    /**
955     * Converts an array of primitive values to an array of appropriate wrapper objects
956     * wrapping the respective primitive values.
957     * 
958     * @param arr An array.
959     * @return A corresponding array of wrapper objects
960     * or {@code null} if the specified array is {@code null}.
961     * @throws IllegalArgumentException if the specified parameter if not an array or if it is an
962     * array of non-primitive elements.
963     */
964    public static Object[] toWrapperArray(Object arr) {
965            
966            if (null == arr)
967                    return null;
968            
969            Class<?> ac = arr.getClass();
970            if (!ac.isArray())
971                    throw new IllegalArgumentException("Cannot convert a non-array to a wrapper array");
972            
973            Class<?> ct = ac.getComponentType();
974            if (!ct.isPrimitive())
975                    throw new IllegalArgumentException("Cannot convert an array of non-primitive component"
976                                                                                     + " type to a wrapper array.");
977                    
978            if (ct.equals(Boolean.TYPE))
979                    return toWrapperArray((boolean[]) arr);                 
980            if (ct.equals(Byte.TYPE))
981                    return toWrapperArray((byte[]) arr);
982            if (ct.equals(Character.TYPE))
983                    return toWrapperArray((char[]) arr);
984            if (ct.equals(Short.TYPE))
985                    return toWrapperArray((short[]) arr);
986            if (ct.equals(Integer.TYPE))
987                    return toWrapperArray((int[]) arr);
988            if (ct.equals(Long.TYPE))
989                    return toWrapperArray((long[]) arr);
990            if (ct.equals(Float.TYPE))
991                    return toWrapperArray((float[]) arr);
992            if (ct.equals(Double.TYPE))
993                    return toWrapperArray((double[]) arr);
994            if (ct.equals(Void.TYPE))                       
995                    throw new IllegalArgumentException("Cannot convert an array-of-void to a wrapper array");
996            
997            throw new Bug("Should never get to this line.");
998    }
999    
1000    } // public class ArrayTools