001    /* JAPI - (Yet another (hopefully) useful) Java API
002     *
003     * Copyright (C) 2004-2006 Christian Hujer
004     *
005     * This program is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU General Public License as
007     * published by the Free Software Foundation; either version 2 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful, but
011     * WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018     * 02111-1307, USA.
019     */
020    
021    package net.sf.japi.util;
022    
023    import java.lang.reflect.Array;
024    import java.util.ArrayList;
025    import java.util.Arrays;
026    import java.util.Collection;
027    import java.util.List;
028    import java.util.Comparator;
029    import java.util.Random;
030    import net.sf.japi.util.filter.Filter;
031    
032    /** This class provides some additional utility methods you might miss in {@link Arrays}.
033     * It is named Arrays2 so you have no problems using both, this class and <code>java.util.Arrays</code> (no name conflict).
034     * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a>
035     * @see Arrays
036     */
037    public final class Arrays2 {
038    
039        /** Random number generator. */
040        private static final Random RND = new Random();
041    
042        /** Private constructor - no instances needed. */
043        private Arrays2() {
044        }
045    
046        /** Concatenate Arrays together.
047         * @param a Arrays to concatenate
048         * @return new Array containing all elements of all arrays
049         */
050        public static double[] concat(final double[]... a) {
051            int ns = 0;
052            for (final double[] anA : a) {
053                ns += anA.length;
054            }
055            final double[] na = new double[ns];
056            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
057                System.arraycopy(a[i], 0, na, np, a[i].length);
058            }
059            return na;
060        }
061    
062        /** Concatenate Arrays together.
063         * @param a Arrays to concatenate
064         * @return new Array containing all elements of all arrays
065         */
066        public static float[] concat(final float[]... a) {
067            int ns = 0;
068            for (final float[] anA : a) {
069                ns += anA.length;
070            }
071            final float[] na = new float[ns];
072            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
073                System.arraycopy(a[i], 0, na, np, a[i].length);
074            }
075            return na;
076        }
077    
078        /** Concatenate Arrays together.
079         * @param a Arrays to concatenate
080         * @return new Array containing all elements of all arrays
081         */
082        public static long[] concat(final long[]... a) {
083            int ns = 0;
084            for (final long[] anA : a) {
085                ns += anA.length;
086            }
087            final long[] na = new long[ns];
088            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
089                System.arraycopy(a[i], 0, na, np, a[i].length);
090            }
091            return na;
092        }
093    
094        /** Concatenate Arrays together.
095         * @param a Arrays to concatenate
096         * @return new Array containing all elements of all arrays
097         */
098        public static int[] concat(final int[]... a) {
099            int ns = 0;
100            for (final int[] anA : a) {
101                ns += anA.length;
102            }
103            final int[] na = new int[ns];
104            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
105                System.arraycopy(a[i], 0, na, np, a[i].length);
106            }
107            return na;
108        }
109    
110        /** Concatenate Arrays together.
111         * @param a Arrays to concatenate
112         * @return new Array containing all elements of all arrays
113         */
114        public static short[] concat(final short[]... a) {
115            int ns = 0;
116            for (final short[] anA : a) {
117                ns += anA.length;
118            }
119            final short[] na = new short[ns];
120            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
121                System.arraycopy(a[i], 0, na, np, a[i].length);
122            }
123            return na;
124        }
125    
126        /** Concatenate Arrays together.
127         * @param a Arrays to concatenate
128         * @return new Array containing all elements of all arrays
129         */
130        public static char[] concat(final char[]... a) {
131            int ns = 0;
132            for (final char[] anA : a) {
133                ns += anA.length;
134            }
135            final char[] na = new char[ns];
136            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
137                System.arraycopy(a[i], 0, na, np, a[i].length);
138            }
139            return na;
140        }
141    
142        /** Concatenate Arrays together.
143         * @param a Arrays to concatenate
144         * @return new Array containing all elements of all arrays
145         */
146        public static byte[] concat(final byte[]... a) {
147            int ns = 0;
148            for (final byte[] anA : a) {
149                ns += anA.length;
150            }
151            final byte[] na = new byte[ns];
152            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
153                System.arraycopy(a[i], 0, na, np, a[i].length);
154            }
155            return na;
156        }
157    
158        /** Concatenate Arrays together.
159         * @param a Arrays to concatenate
160         * @return new Array containing all elements of all arrays
161         */
162        public static boolean[] concat(final boolean[]... a) {
163            int ns = 0;
164            for (final boolean[] anA : a) {
165                ns += anA.length;
166            }
167            final boolean[] na = new boolean[ns];
168            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
169                System.arraycopy(a[i], 0, na, np, a[i].length);
170            }
171            return na;
172        }
173    
174        /** Concatenate Arrays together.
175         * @param a Arrays to concatenate
176         * @return new Array containing all elements of all arrays
177         */
178        public static <T> T[] concat(final T[]... a) {
179            int ns = 0;
180            for (final T[] anA : a) {
181                ns += anA.length;
182            }
183            final T[] na = (T[]) Array.newInstance(a[0].getClass().getComponentType(), ns);
184            for (int i = 0, np = 0; i < a.length; np += a[i].length, i++) {
185                System.arraycopy(a[i], 0, na, np, a[i].length);
186            }
187            return na;
188        }
189    
190        /** Returns an array only containing those elements accepted by the given filter.
191         * The original array remains unmodified.
192         * @param a      Elements to filter
193         * @param filter Filter to use for <var>a</var>
194         * @return array containing only those elements from <var>a</var> accepted by <var>filter</var>
195         * @see Collections2#filter(Collection,Filter)
196         */
197        public static <T> T[] filter(final Filter<? super T> filter, final T... a) {
198            //Class<?> ct = a.getClass().getComponentType();
199            //T[] t = (T[]) Array.newInstance(ct, 0);
200            //List<T> tl = Arrays.asList(a);
201            //List<T> tf = Collections2.filter(tl, filter);
202            //T[] nt = tf.toArray(t);
203            //return nt;
204            //return Collections2.filter(Arrays.asList(a), filter).toArray((T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), 0));
205            final List<T> tl = new ArrayList<T>();
206            for (final T t : a) {
207                if (filter.accept(t)) {
208                    tl.add(t);
209                }
210            }
211            return tl.toArray((T[]) Array.newInstance(a.getClass().getComponentType(), 0));
212        } // eventually add filters for primitive types and provide correspondig methods
213    
214        /** Count elements in an array that are accepted by the given filter.
215         * @param a      Elements to count in
216         * @param filter Filter to use for <var>a</var>
217         * @return number of elements in <var>a</var> accepted by <var>filter</var>
218         */
219        public static <T> int count(final Filter<? super T> filter, final T... a) {
220            int n = 0;
221            for (final T t : a) {
222                if (filter.accept(t)) {
223                    n++;
224                }
225            }
226            return n;
227        } // eventually add filters for primitive types and provide corresponding methods
228    
229        /** Searches the specified array of ints for the specified value using the binary search algorithm.
230         * The array <strong>must</strong> be sorted (as by the <tt>sort</tt> method, above) prior to making this call.
231         * If it is not sorted, the results are undefined (even a runtime exception might occur).
232         * If the array contains multiple elements with the specified value, there is no guarantee which one will be found.
233         * @param a    the array to be searched.
234         * @param key  the value to be searched for.
235         * @param low  lower border (must be <code>&gt;= 0</code>)
236         * @param high upper border (must be <code>&lt; a.length</code>)
237         * @return index of the search key, if it is contained in the list;
238         *         otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
239         *         <i>insertion point</i> is defined as the point at which the
240         *         key would be inserted into the list: the index of the first
241         *         element greater than the key, or <tt>list.size()</tt>, if all
242         *         elements in the list are less than the specified key.  Note
243         *         that this guarantees that the return value will be &gt;= 0 if
244         *         and only if the key is found.
245         * @throws ArrayIndexOutOfBoundsException if <code>low &lt; 0</code> or <code>high &gt;= a.length</code>
246         * @see Arrays#binarySearch(int[],int)
247         * @see Arrays#sort(int[])
248         */
249        public static int binarySearch(final int[] a, final int key, int low, int high) {
250            while (low <= high) {
251                final int mid = low + high >> 1;
252                final int midVal = a[mid];
253                if (midVal < key) {
254                    low = mid + 1;
255                } else if (midVal > key) {
256                    high = mid - 1;
257                } else {
258                    return mid; // key found
259                }
260            }
261            return -(low + 1);  // key not found.
262        }
263    
264        /** Perform a linear search on an array of booleans.
265         * @param z boolean to find in <var>data</var>
266         * @param data array of booleans to perform linear search on
267         * @return index of <var>n</var> in <var>data</var> or -1 if not found
268         */
269        public static int linearSearch(final boolean z, final boolean[] data) {
270            return linearSearch(z, 0, data.length, data);
271        }
272    
273        /** Perform a linear search on an array of chars.
274         * @param c char to find in <var>data</var>
275         * @param data array of chars to perform linear search on
276         * @return index of <var>n</var> in <var>data</var> or -1 if not found
277         */
278        public static int linearSearch(final char c, final char[] data) {
279            return linearSearch(c, 0, data.length, data);
280        }
281    
282        /** Perform a linear search on an array of doubles.
283         * @param d double to find in <var>data</var>
284         * @param data array of doubles to perform linear search on
285         * @return index of <var>n</var> in <var>data</var> or -1 if not found
286         */
287        public static int linearSearch(final double d, final double[] data) {
288            return linearSearch(d, 0, data.length, data);
289        }
290    
291        /** Perform a linear search on an array of floats.
292         * @param f float to find in <var>data</var>
293         * @param data array of floats to perform linear search on
294         * @return index of <var>n</var> in <var>data</var> or -1 if not found
295         */
296        public static int linearSearch(final float f, final float[] data) {
297            return linearSearch(f, 0, data.length, data);
298        }
299    
300        /** Perform a linear search on an array of longs.
301         * @param l long to find in <var>data</var>
302         * @param data array of longs to perform linear search on
303         * @return index of <var>n</var> in <var>data</var> or -1 if not found
304         */
305        public static int linearSearch(final long l, final long[] data) {
306            return linearSearch(l, 0, data.length, data);
307        }
308    
309        /** Perform a linear search on an array of ints.
310         * @param n int to find in <var>data</var>
311         * @param data array of ints to perform linear search on
312         * @return index of <var>n</var> in <var>data</var> or -1 if not found
313         */
314        public static int linearSearch(final int n, final int[] data) {
315            return linearSearch(n, 0, data.length, data);
316        }
317    
318        /** Perform a linear search on an array of shorts.
319         * @param s short to find in <var>data</var>
320         * @param data array of shorts to perform linear search on
321         * @return index of <var>n</var> in <var>data</var> or -1 if not found
322         */
323        public static int linearSearch(final short s, final short[] data) {
324            return linearSearch(s, 0, data.length, data);
325        }
326    
327        /** Perform a linear search on an array of bytes.
328         * @param b byte to find in <var>data</var>
329         * @param data array of bytes to perform linear search on
330         * @return index of <var>n</var> in <var>data</var> or -1 if not found
331         */
332        public static int linearSearch(final byte b, final byte[] data) {
333            return linearSearch(b, 0, data.length, data);
334        }
335    
336        /** Perform a linear search on an array of booleans.
337         * @param z boolean to find in <var>data</var>
338         * @param fromIndex start index within <var>data</var>
339         * @param toIndex end index within <var>data</var>
340         * @param data array of booleans to perform linear search on
341         * @return index of <var>n</var> in <var>data</var> or -1 if not found
342         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
343         */
344        public static int linearSearch(final boolean z, final int fromIndex, final int toIndex, final boolean[] data) {
345            for (int i = fromIndex; i < toIndex; i++) {
346                if (data[i] == z) {
347                    return i;
348                }
349            }
350            return -1;
351        }
352    
353        /** Perform a linear search on an array of chars.
354         * @param c char to find in <var>data</var>
355         * @param fromIndex start index within <var>data</var>
356         * @param toIndex end index within <var>data</var>
357         * @param data array of chars to perform linear search on
358         * @return index of <var>n</var> in <var>data</var> or -1 if not found
359         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
360         */
361        public static int linearSearch(final char c, final int fromIndex, final int toIndex, final char[] data) {
362            for (int i = fromIndex; i < toIndex; i++) {
363                if (data[i] == c) {
364                    return i;
365                }
366            }
367            return -1;
368        }
369    
370        /** Perform a linear search on an array of doubles.
371         * @param d double to find in <var>data</var>
372         * @param fromIndex start index within <var>data</var>
373         * @param toIndex end index within <var>data</var>
374         * @param data array of doubles to perform linear search on
375         * @return index of <var>n</var> in <var>data</var> or -1 if not found
376         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
377         */
378        public static int linearSearch(final double d, final int fromIndex, final int toIndex, final double[] data) {
379            for (int i = fromIndex; i < toIndex; i++) {
380                if (data[i] == d) {
381                    return i;
382                }
383            }
384            return -1;
385        }
386    
387        /** Perform a linear search on an array of floats.
388         * @param f float to find in <var>data</var>
389         * @param fromIndex start index within <var>data</var>
390         * @param toIndex end index within <var>data</var>
391         * @param data array of floats to perform linear search on
392         * @return index of <var>n</var> in <var>data</var> or -1 if not found
393         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
394         */
395        public static int linearSearch(final float f, final int fromIndex, final int toIndex, final float[] data) {
396            for (int i = fromIndex; i < toIndex; i++) {
397                if (data[i] == f) {
398                    return i;
399                }
400            }
401            return -1;
402        }
403    
404        /** Perform a linear search on an array of longs.
405         * @param l long to find in <var>data</var>
406         * @param fromIndex start index within <var>data</var>
407         * @param toIndex end index within <var>data</var>
408         * @param data array of longs to perform linear search on
409         * @return index of <var>n</var> in <var>data</var> or -1 if not found
410         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
411         */
412        public static int linearSearch(final long l, final int fromIndex, final int toIndex, final long[] data) {
413            for (int i = fromIndex; i < toIndex; i++) {
414                if (data[i] == l) {
415                    return i;
416                }
417            }
418            return -1;
419        }
420    
421        /** Perform a linear search on an array of ints.
422         * @param n int to find in <var>data</var>
423         * @param fromIndex start index within <var>data</var>
424         * @param toIndex end index within <var>data</var>
425         * @param data array of ints to perform linear search on
426         * @return index of <var>n</var> in <var>data</var> or -1 if not found
427         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
428         */
429        public static int linearSearch(final int n, final int fromIndex, final int toIndex, final int[] data) {
430            for (int i = fromIndex; i < toIndex; i++) {
431                if (data[i] == n) {
432                    return i;
433                }
434            }
435            return -1;
436        }
437    
438        /** Perform a linear search on an array of shorts.
439         * @param s short to find in <var>data</var>
440         * @param fromIndex start index within <var>data</var>
441         * @param toIndex end index within <var>data</var>
442         * @param data array of shorts to perform linear search on
443         * @return index of <var>n</var> in <var>data</var> or -1 if not found
444         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
445         */
446        public static int linearSearch(final short s, final int fromIndex, final int toIndex, final short[] data) {
447            for (int i = fromIndex; i < toIndex; i++) {
448                if (data[i] == s) {
449                    return i;
450                }
451            }
452            return -1;
453        }
454    
455        /** Perform a linear search on an array of bytes.
456         * @param b byte to find in <var>data</var>
457         * @param fromIndex start index within <var>data</var>
458         * @param toIndex end index within <var>data</var>
459         * @param data array of bytes to perform linear search on
460         * @return index of <var>n</var> in <var>data</var> or -1 if not found
461         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
462         */
463        public static int linearSearch(final byte b, final int fromIndex, final int toIndex, final byte[] data) {
464            for (int i = fromIndex; i < toIndex; i++) {
465                if (data[i] == b) {
466                    return i;
467                }
468            }
469            return -1;
470        }
471    
472        /** Perform a linear search on an array of Objects.
473         * @param o Object to find in <var>data</var>
474         * @param data array of Objects to perform linear search on
475         * @return index of <var>n</var> in <var>data</var> or -1 if not found
476         */
477        public static int linearIdentitySearch(final Object o, final Object[] data) {
478            return linearIdentitySearch(o, 0, data.length, data);
479        }
480    
481        /** Perform a linear search on an array of Objects.
482         * @param o Object to find in <var>data</var>
483         * @param fromIndex start index within <var>data</var>
484         * @param toIndex end index within <var>data</var>
485         * @param data array of Objects to perform linear search on
486         * @return index of <var>n</var> in <var>data</var> or -1 if not found
487         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
488         */
489        @SuppressWarnings({"ObjectEquality"})
490        public static int linearIdentitySearch(final Object o, final int fromIndex, final int toIndex, final Object[] data) {
491            for (int i = fromIndex; i < toIndex; i++) {
492                if (data[i] == o) {
493                    return i;
494                }
495            }
496            return -1;
497        }
498    
499        /** Perform a linear search on an array of Objects.
500         * @param o Object to find in <var>data</var>
501         * @param data array of Objects to perform linear search on
502         * @return index of <var>n</var> in <var>data</var> or -1 if not found
503         */
504        public static int linearEqualitySearch(final Object o, final Object[] data) {
505            return linearEqualitySearch(o, 0, data.length, data);
506        }
507    
508        /** Perform a linear search on an array of Objects.
509         * @param o Object to find in <var>data</var>
510         * @param fromIndex start index within <var>data</var>
511         * @param toIndex end index within <var>data</var>
512         * @param data array of Objects to perform linear search on
513         * @return index of <var>n</var> in <var>data</var> or -1 if not found
514         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
515         */
516        public static int linearEqualitySearch(final Object o, final int fromIndex, final int toIndex, final Object[] data) {
517            for (int i = fromIndex; i < toIndex; i++) {
518                if (o == null && data[i] == null || data[i].equals(o)) {
519                    return i;
520                }
521            }
522            return -1;
523        }
524    
525        /** Perform a linear search on an array of Objects.
526         * @param o Object to find in <var>data</var>
527         * @param data array of Objects to perform linear search on
528         * @return index of <var>n</var> in <var>data</var> or -1 if not found
529         */
530        public static <T> int linearComparisonSearch(final T o, final T[] data, final Comparator<? super T> comp) {
531            return linearComparisonSearch(o, 0, data.length, data, comp);
532        }
533    
534        /** Perform a linear search on an array of Objects.
535         * @param o Object to find in <var>data</var>
536         * @param fromIndex start index within <var>data</var>
537         * @param toIndex end index within <var>data</var>
538         * @param data array of Objects to perform linear search on
539         * @return index of <var>n</var> in <var>data</var> or -1 if not found
540         * @throws ArrayIndexOutOfBoundsException in case <code><var>fromIndex</var> &lt; 0</code> or <code><var>toIndex</var> &gt;= data.length</code>
541         */
542        public static <T> int linearComparisonSearch(final T o, final int fromIndex, final int toIndex, final T[] data, final Comparator<? super T> comp) {
543            for (int i = fromIndex; i < toIndex; i++) {
544                if (comp.compare(o, data[i]) == 0) {
545                    return i;
546                }
547            }
548            return -1;
549        }
550    
551        /** Shuffle an array of booleans.
552         * @param array Array to shuffle
553         */
554        public static void shuffle(final boolean[] array) {
555            shuffle(array, 0, array.length, RND);
556        }
557    
558        /** Shuffle an array of booleans.
559         * @param array Array to shuffle
560         * @param rnd Random Number Generator
561         */
562        public static void shuffle(final boolean[] array, final Random rnd) {
563            shuffle(array, 0, array.length, rnd);
564        }
565    
566        /** Shuffle an array of booleans.
567         * @param array Array to shuffle
568         * @param fromIndex Start index to shuffle at (inclusive)
569         * @param toIndex End index to shuffle at (exclusive)
570         */
571        public static void shuffle(final boolean[] array, final int fromIndex, final int toIndex) {
572            shuffle(array, fromIndex, toIndex, RND);
573        }
574    
575        /** Shuffle an array of booleans.
576         * @param array Array to shuffle
577         * @param fromIndex Start index to shuffle at (inclusive)
578         * @param toIndex End index to shuffle at (exclusive)
579         * @param rnd Random number generator
580         */
581        public static void shuffle(final boolean[] array, final int fromIndex, final int toIndex, final Random rnd) {
582            for (int i = fromIndex; i < toIndex; i++) {
583                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
584                final boolean cache = array[i];
585                array[i] = array[j];
586                array[j] = cache;
587            }
588        }
589    
590        /** Shuffle an array of chars.
591         * @param array Array to shuffle
592         */
593        public static void shuffle(final char[] array) {
594            shuffle(array, 0, array.length, RND);
595        }
596    
597        /** Shuffle an array of chars.
598         * @param array Array to shuffle
599         * @param rnd Random Number Generator
600         */
601        public static void shuffle(final char[] array, final Random rnd) {
602            shuffle(array, 0, array.length, rnd);
603        }
604    
605        /** Shuffle an array of chars.
606         * @param array Array to shuffle
607         * @param fromIndex Start index to shuffle at (inclusive)
608         * @param toIndex End index to shuffle at (exclusive)
609         */
610        public static void shuffle(final char[] array, final int fromIndex, final int toIndex) {
611            shuffle(array, fromIndex, toIndex, RND);
612        }
613    
614        /** Shuffle an array of chars.
615         * @param array Array to shuffle
616         * @param fromIndex Start index to shuffle at (inclusive)
617         * @param toIndex End index to shuffle at (exclusive)
618         * @param rnd Random number generator
619         */
620        public static void shuffle(final char[] array, final int fromIndex, final int toIndex, final Random rnd) {
621            for (int i = fromIndex; i < toIndex; i++) {
622                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
623                final char cache = array[i];
624                array[i] = array[j];
625                array[j] = cache;
626            }
627        }
628    
629        /** Shuffle an array of bytes.
630         * @param array Array to shuffle
631         */
632        public static void shuffle(final byte[] array) {
633            shuffle(array, 0, array.length, RND);
634        }
635    
636        /** Shuffle an array of bytes.
637         * @param array Array to shuffle
638         * @param rnd Random Number Generator
639         */
640        public static void shuffle(final byte[] array, final Random rnd) {
641            shuffle(array, 0, array.length, rnd);
642        }
643    
644        /** Shuffle an array of bytes.
645         * @param array Array to shuffle
646         * @param fromIndex Start index to shuffle at (inclusive)
647         * @param toIndex End index to shuffle at (exclusive)
648         */
649        public static void shuffle(final byte[] array, final int fromIndex, final int toIndex) {
650            shuffle(array, fromIndex, toIndex, RND);
651        }
652    
653        /** Shuffle an array of bytes.
654         * @param array Array to shuffle
655         * @param fromIndex Start index to shuffle at (inclusive)
656         * @param toIndex End index to shuffle at (exclusive)
657         * @param rnd Random number generator
658         */
659        public static void shuffle(final byte[] array, final int fromIndex, final int toIndex, final Random rnd) {
660            for (int i = fromIndex; i < toIndex; i++) {
661                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
662                final byte cache = array[i];
663                array[i] = array[j];
664                array[j] = cache;
665            }
666        }
667    
668        /** Shuffle an array of shorts.
669         * @param array Array to shuffle
670         */
671        public static void shuffle(final short[] array) {
672            shuffle(array, 0, array.length, RND);
673        }
674    
675        /** Shuffle an array of shorts.
676         * @param array Array to shuffle
677         * @param rnd Random Number Generator
678         */
679        public static void shuffle(final short[] array, final Random rnd) {
680            shuffle(array, 0, array.length, rnd);
681        }
682    
683        /** Shuffle an array of shorts.
684         * @param array Array to shuffle
685         * @param fromIndex Start index to shuffle at (inclusive)
686         * @param toIndex End index to shuffle at (exclusive)
687         */
688        public static void shuffle(final short[] array, final int fromIndex, final int toIndex) {
689            shuffle(array, fromIndex, toIndex, RND);
690        }
691    
692        /** Shuffle an array of shorts.
693         * @param array Array to shuffle
694         * @param fromIndex Start index to shuffle at (inclusive)
695         * @param toIndex End index to shuffle at (exclusive)
696         * @param rnd Random number generator
697         */
698        public static void shuffle(final short[] array, final int fromIndex, final int toIndex, final Random rnd) {
699            for (int i = fromIndex; i < toIndex; i++) {
700                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
701                final short cache = array[i];
702                array[i] = array[j];
703                array[j] = cache;
704            }
705        }
706    
707        /** Shuffle an array of ints.
708         * @param array Array to shuffle
709         */
710        public static void shuffle(final int[] array) {
711            shuffle(array, 0, array.length, RND);
712        }
713    
714        /** Shuffle an array of ints.
715         * @param array Array to shuffle
716         * @param rnd Random Number Generator
717         */
718        public static void shuffle(final int[] array, final Random rnd) {
719            shuffle(array, 0, array.length, rnd);
720        }
721    
722        /** Shuffle an array of ints.
723         * @param array Array to shuffle
724         * @param fromIndex Start index to shuffle at (inclusive)
725         * @param toIndex End index to shuffle at (exclusive)
726         */
727        public static void shuffle(final int[] array, final int fromIndex, final int toIndex) {
728            shuffle(array, fromIndex, toIndex, RND);
729        }
730    
731        /** Shuffle an array of ints.
732         * @param array Array to shuffle
733         * @param fromIndex Start index to shuffle at (inclusive)
734         * @param toIndex End index to shuffle at (exclusive)
735         * @param rnd Random number generator
736         */
737        public static void shuffle(final int[] array, final int fromIndex, final int toIndex, final Random rnd) {
738            for (int i = fromIndex; i < toIndex; i++) {
739                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
740                final int cache = array[i];
741                array[i] = array[j];
742                array[j] = cache;
743            }
744        }
745    
746        /** Shuffle an array of longs.
747         * @param array Array to shuffle
748         */
749        public static void shuffle(final long[] array) {
750            shuffle(array, 0, array.length, RND);
751        }
752    
753        /** Shuffle an array of longs.
754         * @param array Array to shuffle
755         * @param rnd Random Number Generator
756         */
757        public static void shuffle(final long[] array, final Random rnd) {
758            shuffle(array, 0, array.length, rnd);
759        }
760    
761        /** Shuffle an array of longs.
762         * @param array Array to shuffle
763         * @param fromIndex Start index to shuffle at (inclusive)
764         * @param toIndex End index to shuffle at (exclusive)
765         */
766        public static void shuffle(final long[] array, final int fromIndex, final int toIndex) {
767            shuffle(array, fromIndex, toIndex, RND);
768        }
769    
770        /** Shuffle an array of longs.
771         * @param array Array to shuffle
772         * @param fromIndex Start index to shuffle at (inclusive)
773         * @param toIndex End index to shuffle at (exclusive)
774         * @param rnd Random number generator
775         */
776        public static void shuffle(final long[] array, final int fromIndex, final int toIndex, final Random rnd) {
777            for (int i = fromIndex; i < toIndex; i++) {
778                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
779                final long cache = array[i];
780                array[i] = array[j];
781                array[j] = cache;
782            }
783        }
784    
785        /** Shuffle an array of floats.
786         * @param array Array to shuffle
787         */
788        public static void shuffle(final float[] array) {
789            shuffle(array, 0, array.length, RND);
790        }
791    
792        /** Shuffle an array of floats.
793         * @param array Array to shuffle
794         * @param rnd Random Number Generator
795         */
796        public static void shuffle(final float[] array, final Random rnd) {
797            shuffle(array, 0, array.length, rnd);
798        }
799    
800        /** Shuffle an array of floats.
801         * @param array Array to shuffle
802         * @param fromIndex Start index to shuffle at (inclusive)
803         * @param toIndex End index to shuffle at (exclusive)
804         */
805        public static void shuffle(final float[] array, final int fromIndex, final int toIndex) {
806            shuffle(array, fromIndex, toIndex, RND);
807        }
808    
809        /** Shuffle an array of floats.
810         * @param array Array to shuffle
811         * @param fromIndex Start index to shuffle at (inclusive)
812         * @param toIndex End index to shuffle at (exclusive)
813         * @param rnd Random number generator
814         */
815        public static void shuffle(final float[] array, final int fromIndex, final int toIndex, final Random rnd) {
816            for (int i = fromIndex; i < toIndex; i++) {
817                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
818                final float cache = array[i];
819                array[i] = array[j];
820                array[j] = cache;
821            }
822        }
823    
824        /** Shuffle an array of doubles.
825         * @param array Array to shuffle
826         */
827        public static void shuffle(final double[] array) {
828            shuffle(array, 0, array.length, RND);
829        }
830    
831        /** Shuffle an array of doubles.
832         * @param array Array to shuffle
833         * @param rnd Random Number Generator
834         */
835        public static void shuffle(final double[] array, final Random rnd) {
836            shuffle(array, 0, array.length, rnd);
837        }
838    
839        /** Shuffle an array of doubles.
840         * @param array Array to shuffle
841         * @param fromIndex Start index to shuffle at (inclusive)
842         * @param toIndex End index to shuffle at (exclusive)
843         */
844        public static void shuffle(final double[] array, final int fromIndex, final int toIndex) {
845            shuffle(array, fromIndex, toIndex, RND);
846        }
847    
848        /** Shuffle an array of doubles.
849         * @param array Array to shuffle
850         * @param fromIndex Start index to shuffle at (inclusive)
851         * @param toIndex End index to shuffle at (exclusive)
852         * @param rnd Random number generator
853         */
854        public static void shuffle(final double[] array, final int fromIndex, final int toIndex, final Random rnd) {
855            for (int i = fromIndex; i < toIndex; i++) {
856                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
857                final double cache = array[i];
858                array[i] = array[j];
859                array[j] = cache;
860            }
861        }
862    
863        /** Shuffle an array of Objects.
864         * @param array Array to shuffle
865         */
866        public static void shuffle(final Object[] array) {
867            shuffle(array, 0, array.length, RND);
868        }
869    
870        /** Shuffle an array of Objects.
871         * @param array Array to shuffle
872         * @param rnd Random Number Generator
873         */
874        public static void shuffle(final Object[] array, final Random rnd) {
875            shuffle(array, 0, array.length, rnd);
876        }
877    
878        /** Shuffle an array of Objects.
879         * @param array Array to shuffle
880         * @param fromIndex Start index to shuffle at (inclusive)
881         * @param toIndex End index to shuffle at (exclusive)
882         */
883        public static void shuffle(final Object[] array, final int fromIndex, final int toIndex) {
884            shuffle(array, fromIndex, toIndex, RND);
885        }
886    
887        /** Shuffle an array of Objects.
888         * @param array Array to shuffle
889         * @param fromIndex Start index to shuffle at (inclusive)
890         * @param toIndex End index to shuffle at (exclusive)
891         * @param rnd Random number generator
892         */
893        public static void shuffle(final Object[] array, final int fromIndex, final int toIndex, final Random rnd) {
894            for (int i = fromIndex; i < toIndex; i++) {
895                final int j = rnd.nextInt(toIndex - fromIndex) + fromIndex;
896                final Object cache = array[i];
897                array[i] = array[j];
898                array[j] = cache;
899            }
900        }
901    
902        /** Count the frequency of a specific boolean in an unsorted array of booleans.
903         * @param array Array of booleans to count in
904         * @param val boolean value to count frequency of
905         * @return frequency of <var>val</var> in <var>array</var>
906         */
907        public static int freq(final boolean[] array, final boolean val) {
908            return freq(array, 0, array.length, val);
909        }
910    
911        /** Count the frequency of a specific boolean in an unsorted array of booleans.
912         * @param array Array of booleans to count in
913         * @param fromIndex Start index to shuffle at (inclusive)
914         * @param toIndex End index to shuffle at (exclusive)
915         * @param val boolean value to count frequency of
916         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
917         */
918        public static int freq(final boolean[] array, final int fromIndex, final int toIndex, final boolean val) {
919            int count = 0;
920            for (int i = fromIndex; i < toIndex; i++) {
921                if (array[i] == val) {
922                    count++;
923                }
924            }
925            return count;
926        }
927    
928        /** Count the frequency of a specific char in an unsorted array of chars.
929         * @param array Array of chars to count in
930         * @param val char value to count frequency of
931         * @return frequency of <var>val</var> in <var>array</var>
932         */
933        public static int freq(final char[] array, final char val) {
934            return freq(array, 0, array.length, val);
935        }
936    
937        /** Count the frequency of a specific char in an unsorted array of chars.
938         * @param array Array of chars to count in
939         * @param fromIndex Start index to shuffle at (inclusive)
940         * @param toIndex End index to shuffle at (exclusive)
941         * @param val char value to count frequency of
942         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
943         */
944        public static int freq(final char[] array, final int fromIndex, final int toIndex, final char val) {
945            int count = 0;
946            for (int i = fromIndex; i < toIndex; i++) {
947                if (array[i] == val) {
948                    count++;
949                }
950            }
951            return count;
952        }
953    
954        /** Count the frequency of a specific byte in an unsorted array of bytes.
955         * @param array Array of bytes to count in
956         * @param val byte value to count frequency of
957         * @return frequency of <var>val</var> in <var>array</var>
958         */
959        public static int freq(final byte[] array, final byte val) {
960            return freq(array, 0, array.length, val);
961        }
962    
963        /** Count the frequency of a specific byte in an unsorted array of bytes.
964         * @param array Array of bytes to count in
965         * @param fromIndex Start index to shuffle at (inclusive)
966         * @param toIndex End index to shuffle at (exclusive)
967         * @param val byte value to count frequency of
968         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
969         */
970        public static int freq(final byte[] array, final int fromIndex, final int toIndex, final byte val) {
971            int count = 0;
972            for (int i = fromIndex; i < toIndex; i++) {
973                if (array[i] == val) {
974                    count++;
975                }
976            }
977            return count;
978        }
979    
980        /** Count the frequency of a specific short in an unsorted array of shorts.
981         * @param array Array of shorts to count in
982         * @param val short value to count frequency of
983         * @return frequency of <var>val</var> in <var>array</var>
984         */
985        public static int freq(final short[] array, final short val) {
986            return freq(array, 0, array.length, val);
987        }
988    
989        /** Count the frequency of a specific short in an unsorted array of shorts.
990         * @param array Array of shorts to count in
991         * @param fromIndex Start index to shuffle at (inclusive)
992         * @param toIndex End index to shuffle at (exclusive)
993         * @param val short value to count frequency of
994         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
995         */
996        public static int freq(final short[] array, final int fromIndex, final int toIndex, final short val) {
997            int count = 0;
998            for (int i = fromIndex; i < toIndex; i++) {
999                if (array[i] == val) {
1000                    count++;
1001                }
1002            }
1003            return count;
1004        }
1005    
1006        /** Count the frequency of a specific int in an unsorted array of ints.
1007         * @param array Array of ints to count in
1008         * @param val int value to count frequency of
1009         * @return frequency of <var>val</var> in <var>array</var>
1010         */
1011        public static int freq(final int[] array, final int val) {
1012            return freq(array, 0, array.length, val);
1013        }
1014    
1015        /** Count the frequency of a specific int in an unsorted array of ints.
1016         * @param array Array of ints to count in
1017         * @param fromIndex Start index to shuffle at (inclusive)
1018         * @param toIndex End index to shuffle at (exclusive)
1019         * @param val int value to count frequency of
1020         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
1021         */
1022        public static int freq(final int[] array, final int fromIndex, final int toIndex, final int val) {
1023            int count = 0;
1024            for (int i = fromIndex; i < toIndex; i++) {
1025                if (array[i] == val) {
1026                    count++;
1027                }
1028            }
1029            return count;
1030        }
1031    
1032        /** Count the frequency of a specific long in an unsorted array of longs.
1033         * @param array Array of longs to count in
1034         * @param val long value to count frequency of
1035         * @return frequency of <var>val</var> in <var>array</var>
1036         */
1037        public static int freq(final long[] array, final long val) {
1038            return freq(array, 0, array.length, val);
1039        }
1040    
1041        /** Count the frequency of a specific long in an unsorted array of longs.
1042         * @param array Array of longs to count in
1043         * @param fromIndex Start index to shuffle at (inclusive)
1044         * @param toIndex End index to shuffle at (exclusive)
1045         * @param val long value to count frequency of
1046         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
1047         */
1048        public static int freq(final long[] array, final int fromIndex, final int toIndex, final long val) {
1049            int count = 0;
1050            for (int i = fromIndex; i < toIndex; i++) {
1051                if (array[i] == val) {
1052                    count++;
1053                }
1054            }
1055            return count;
1056        }
1057    
1058        /** Count the frequency of a specific float in an unsorted array of floats.
1059         * @param array Array of floats to count in
1060         * @param val float value to count frequency of
1061         * @return frequency of <var>val</var> in <var>array</var>
1062         */
1063        public static int freq(final float[] array, final float val) {
1064            return freq(array, 0, array.length, val);
1065        }
1066    
1067        /** Count the frequency of a specific float in an unsorted array of floats.
1068         * @param array Array of floats to count in
1069         * @param fromIndex Start index to shuffle at (inclusive)
1070         * @param toIndex End index to shuffle at (exclusive)
1071         * @param val float value to count frequency of
1072         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
1073         */
1074        public static int freq(final float[] array, final int fromIndex, final int toIndex, final float val) {
1075            int count = 0;
1076            for (int i = fromIndex; i < toIndex; i++) {
1077                if (array[i] == val) {
1078                    count++;
1079                }
1080            }
1081            return count;
1082        }
1083    
1084        /** Count the frequency of a specific double in an unsorted array of doubles.
1085         * @param array Array of doubles to count in
1086         * @param val double value to count frequency of
1087         * @return frequency of <var>val</var> in <var>array</var>
1088         */
1089        public static int freq(final double[] array, final double val) {
1090            return freq(array, 0, array.length, val);
1091        }
1092    
1093        /** Count the frequency of a specific double in an unsorted array of doubles.
1094         * @param array Array of doubles to count in
1095         * @param fromIndex Start index to shuffle at (inclusive)
1096         * @param toIndex End index to shuffle at (exclusive)
1097         * @param val double value to count frequency of
1098         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
1099         */
1100        public static int freq(final double[] array, final int fromIndex, final int toIndex, final double val) {
1101            int count = 0;
1102            for (int i = fromIndex; i < toIndex; i++) {
1103                if (array[i] == val) {
1104                    count++;
1105                }
1106            }
1107            return count;
1108        }
1109    
1110        /** Count the frequency of a specific Object in an unsorted array of Objects.
1111         * @param array Array of Objects to count in
1112         * @param val Object value to count frequency of
1113         * @return frequency of <var>val</var> in <var>array</var>
1114         */
1115        public static int freqIdentity(final Object[] array, final Object val) {
1116            return freqIdentity(array, 0, array.length, val);
1117        }
1118    
1119        /** Count the frequency of a specific Object in an unsorted array of Objects.
1120         * @param array Array of Objects to count in
1121         * @param fromIndex Start index to shuffle at (inclusive)
1122         * @param toIndex End index to shuffle at (exclusive)
1123         * @param val Object value to count frequency of
1124         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
1125         */
1126        @SuppressWarnings({"ObjectEquality"})
1127        public static int freqIdentity(final Object[] array, final int fromIndex, final int toIndex, final Object val) {
1128            int count = 0;
1129            for (int i = fromIndex; i < toIndex; i++) {
1130                if (array[i] == val) {
1131                    count++;
1132                }
1133            }
1134            return count;
1135        }
1136    
1137        /** Count the frequency of a specific Object in an unsorted array of Objects.
1138         * @param array Array of Objects to count in
1139         * @param val Object value to count frequency of
1140         * @return frequency of <var>val</var> in <var>array</var>
1141         */
1142        public static int freqEquals(final Object[] array, final Object val) {
1143            return freqEquals(array, 0, array.length, val);
1144        }
1145    
1146        /** Count the frequency of a specific Object in an unsorted array of Objects.
1147         * @param array Array of Objects to count in
1148         * @param fromIndex Start index to shuffle at (inclusive)
1149         * @param toIndex End index to shuffle at (exclusive)
1150         * @param val Object value to count frequency of
1151         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
1152         */
1153        public static int freqEquals(final Object[] array, final int fromIndex, final int toIndex, final Object val) {
1154            if (val == null) {
1155                return freqIdentity(array, fromIndex, toIndex, val);
1156            }
1157            int count = 0;
1158            for (int i = fromIndex; i < toIndex; i++) {
1159                if (val.equals(array[i])) {
1160                    count++;
1161                }
1162            }
1163            return count;
1164        }
1165    
1166        /** Count the frequency of a specific Comparable in an unsorted array of Comparables.
1167         * @param array Array of Comparables to count in
1168         * @param val Comparable value to count frequency of
1169         * @return frequency of <var>val</var> in <var>array</var>
1170         */
1171        public static <T extends Comparable<T>> int freqComparable(final T[] array, final T val) {
1172            return freqComparable(array, 0, array.length, val);
1173        }
1174    
1175        /** Count the frequency of a specific Comparable in an unsorted array of Comparables.
1176         * @param array Array of Comparables to count in
1177         * @param fromIndex Start index to shuffle at (inclusive)
1178         * @param toIndex End index to shuffle at (exclusive)
1179         * @param val Comparable value to count frequency of
1180         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
1181         */
1182        public static <T extends Comparable<T>> int freqComparable(final T[] array, final int fromIndex, final int toIndex, final T val) {
1183            if (val == null) {
1184                return freqIdentity(array, fromIndex, toIndex, val);
1185            }
1186            int count = 0;
1187            for (int i = fromIndex; i < toIndex; i++) {
1188                if (val.compareTo(array[i]) == 0) {
1189                    count++;
1190                }
1191            }
1192            return count;
1193        }
1194    
1195        /** Count the frequency of a specific Object in an unsorted array of Objects.
1196         * @param array Array of Objects to count in
1197         * @param val Object value to count frequency of
1198         * @param comparator Comparator for comparing objects
1199         * @return frequency of <var>val</var> in <var>array</var>
1200         */
1201        public static <T> int freqComparator(final T[] array, final T val, final Comparator<? super T> comparator) {
1202            return freqComparator(array, 0, array.length, val, comparator);
1203        }
1204    
1205        /** Count the frequency of a specific Object in an unsorted array of Objects.
1206         * @param array Array of Objects to count in
1207         * @param fromIndex Start index to shuffle at (inclusive)
1208         * @param toIndex End index to shuffle at (exclusive)
1209         * @param val Object value to count frequency of
1210         * @param comparator Comparator for comparing objects
1211         * @return frequency of <var>val</var> in <var>array</var> between <var>fromIndex</var> and <var>toIndex</var>
1212         */
1213        public static <T> int freqComparator(final T[] array, final int fromIndex, final int toIndex, final T val, final Comparator<? super T> comparator) {
1214            int count = 0;
1215            for (int i = fromIndex; i < toIndex; i++) {
1216                if (comparator.compare(array[i], val) == 0) {
1217                    count++;
1218                }
1219            }
1220            return count;
1221        }
1222    
1223        /* TODO: Planned methods for future versions:
1224        * - frequency for sorted arrays
1225        * - min for all types of arrays (unsorted; for sorted use a[0])
1226        * - min for all types of arrays (unsorted; for sorted use a[0]) with ranges
1227        * - avg for numeric types of arrays (unsorted; primitives, Number, Character, Color, Date, Calendar)
1228        * - avg for numeric types of arrays (unsorted; primitives, Number, Character, Color, Date, Calendar) with ranges
1229        * - max for all types of arrays (unsorted; for sorted use a[a.length - 1])
1230        * - max for all types of arrays (unsorted; for sorted use a[a.length - 1]) with ranges
1231        * - sum for numeric types of arrays (unsorted; primitives, Number, Character, Color, Date, Calendar)
1232        * - sum for numeric types of arrays (unsorted; primitives, Number, Character, Color, Date, Calendar) with ranges
1233        * - med (median) for numeric types of arrays (unsorted; primitives, Number, Character, Color, Date, Calendar)
1234        * - med (median) for numeric types of arrays (unsorted; primitives, Number, Character, Color, Date, Calendar) with ranges
1235        * - product for numeric types of arrays (unsorted; primitives, Number, Character, Color, Date, Calendar)
1236        * - product for numeric types of arrays (unsorted; primitives, Number, Character, Color, Date, Calendar) with ranges
1237        * - binarySearch for all types of arrays (sorted) with ranges with Comparators
1238        * - binarySearch for all types of arrays (sorted) with ranges without Comparators
1239        * - equals for all types of arrays with ranges
1240        * - hashCode for all types of arrays with ranges
1241        * - toString for all types of arrays with ranges
1242        * - asList for all types of arrays with ranges
1243        * - replaceAll for all types of arrays
1244        * - replaceAll for all types of arrays with ranges
1245        * - replaceFirst for all types of arrays
1246        * - replaceFirst for all types of arrays with ranges
1247        * - replaceLast for all types of arrays
1248        * - replaceLast for all types of arrays with ranges
1249        * - subarray (create a new array as part of an old array) for all types of arrays with ranges
1250        * - isSorted for all types of arrays with and without Comparators
1251        * - reverse for all types of arrays
1252        * - create an array by repeating an element
1253        *
1254        * Eventually provide native implementation of some methods for performance reasons.
1255        */
1256    
1257    } // class Arrays2