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>>= 0</code>)
236 * @param high upper border (must be <code>< 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 >= 0 if
244 * and only if the key is found.
245 * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or <code>high >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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> < 0</code> or <code><var>toIndex</var> >= 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