001 /*
002 * Java Genetic Algorithm Library (jenetics-1.6.0).
003 * Copyright (c) 2007-2014 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019 */
020 package org.jenetics.util;
021
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024
025 import java.util.Arrays;
026 import java.util.Collections;
027 import java.util.Comparator;
028 import java.util.Iterator;
029 import java.util.List;
030 import java.util.Random;
031
032
033 /**
034 * Static helper methods concerning arrays.
035 *
036 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
037 * @since 1.0
038 * @version 1.5 — <em>$Date: 2014-02-15 $</em>
039 */
040 public final class arrays extends StaticObject {
041 private arrays() {}
042
043
044 /**
045 * Unified method for calculating the hash code of every {@link Seq}
046 * implementation. The hash code is defined as followed:
047 *
048 * [code]
049 * int hashCode = 1;
050 * final Iterator<E> it = seq.iterator();
051 * while (it.hasNext()) {
052 * final E obj = it.next();
053 * hashCode = 31*hashCode + (obj == null ? 0 : obj.hashCode());
054 * }
055 * [/code]
056 *
057 * @see Seq#hashCode()
058 * @see List#hashCode()
059 *
060 * @param seq the sequence to calculate the hash code for.
061 * @return the hash code of the given sequence.
062 */
063 public static int hashCode(final Seq<?> seq) {
064 int hash = 1;
065 for (Object element : seq) {
066 hash = 31*hash + (element == null ? 0: element.hashCode());
067 }
068 return hash;
069 }
070
071 /**
072 * Unified method for compare to sequences for equality.
073 *
074 * @see Seq#equals(Object)
075 *
076 * @param seq the sequence to test for equality.
077 * @param obj the object to test for equality with the sequence.
078 * @return {@code true} if the given objects are sequences and contain the
079 * same objects in the same order, {@code false} otherwise.
080 */
081 public static boolean equals(final Seq<?> seq, final Object obj) {
082 if (obj == seq) {
083 return true;
084 }
085 if (!(obj instanceof Seq<?>)) {
086 return false;
087 }
088
089 final Seq<?> other = (Seq<?>)obj;
090 boolean equals = (seq.length() == other.length());
091 for (int i = seq.length(); equals && --i >= 0;) {
092 final Object element = seq.get(i);
093 if (element != null) {
094 equals = element.equals(other.get(i));
095 } else {
096 equals = other.get(i) == null;
097 }
098 }
099 return equals;
100 }
101
102 /**
103 * Swap two elements of an given list.
104 *
105 * @param <T> the list type.
106 * @param list the array
107 * @param i index of the first list element.
108 * @param j index of the second list element.
109 * @throws IndexOutOfBoundsException if <tt>i < 0</tt> or
110 * <tt>j < 0</tt> or <tt>i > a.length</tt> or
111 * <tt>j > a.length</tt>
112 * @throws NullPointerException if the give list is {@code null}.
113 *
114 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
115 */
116 @Deprecated
117 public static <T> void swap(final List<T> list, final int i, final int j) {
118 final T old = list.get(i);
119 list.set(i, list.get(j));
120 list.set(j, old);
121 }
122
123 /**
124 * Swap two elements of an given array.
125 *
126 * @param <T> the array type.
127 * @param array the array
128 * @param i index of the first array element.
129 * @param j index of the second array element.
130 * @throws IndexOutOfBoundsException if <tt>i < 0</tt> or
131 * <tt>j < 0</tt> or <tt>i > a.length</tt> or
132 * <tt>j > a.length</tt>
133 * @throws NullPointerException if the give array is {@code null}.
134 *
135 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
136 */
137 @Deprecated
138 public static <T> void swap(final T[] array, final int i, final int j) {
139 final T old = array[i];
140 array[i] = array[j];
141 array[j] = old;
142 }
143
144 /**
145 * Swap two byte elements of the given array.
146 *
147 * @param array the array
148 * @param i index of the first array element.
149 * @param j index of the second array element.
150 * @throws IndexOutOfBoundsException if <tt>i < 0</tt> or
151 * <tt>j < 0</tt> or <tt>i > a.length</tt> or
152 * <tt>j > a.length</tt>
153 * @throws NullPointerException if the give array is {@code null}.
154 *
155 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
156 */
157 @Deprecated
158 public static void swap(final byte[] array, final int i, final int j) {
159 final byte old = array[i];
160 array[i] = array[j];
161 array[j] = old;
162 }
163
164 /**
165 * Swap two elements of an given array.
166 *
167 * @param array the array
168 * @param i index of the first array element.
169 * @param j index of the second array element.
170 * @throws IndexOutOfBoundsException if <tt>i < 0</tt> or
171 * <tt>j < 0</tt> or <tt>i > a.length</tt> or
172 * <tt>j > a.length</tt>
173 * @throws NullPointerException if the give array is {@code null}.
174 *
175 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
176 */
177 @Deprecated
178 public static void swap(final int[] array, final int i, final int j) {
179 final int old = array[i];
180 array[i] = array[j];
181 array[j] = old;
182 }
183
184 /**
185 * Calls the sort method on the {@link Arrays} class.
186 *
187 * @throws NullPointerException if the give array is {@code null}.
188 * @throws UnsupportedOperationException if the array is sealed
189 * ({@code array.isSealed() == true}).
190 */
191 public static <T extends Object & Comparable<? super T>> MSeq<T>
192 sort(final MSeq<T> array)
193 {
194 Collections.sort(array.asList());
195 return array;
196 }
197
198 /**
199 * Test whether the given array is sorted in ascending order.
200 *
201 * @param seq the array to test.
202 * @return {@code true} if the given {@code array} is sorted in ascending
203 * order, {@code false} otherwise.
204 * @throws NullPointerException if the given array or one of it's element is
205 * {@code null}.
206 */
207 public static <T extends Object & Comparable<? super T>>
208 boolean isSorted(final Seq<T> seq)
209 {
210 boolean sorted = true;
211 for (int i = 0, n = seq.length() - 1; i < n && sorted; ++i) {
212 sorted = seq.get(i).compareTo(seq.get(i + 1)) <= 0;
213 }
214
215 return sorted;
216 }
217
218 /**
219 * Test whether the given array is sorted in ascending order. The order of
220 * the array elements is defined by the given comparator.
221 *
222 * @param seq the array to test.
223 * @param comparator the comparator which defines the order.
224 * @return {@code true} if the given {@code array} is sorted in ascending
225 * order, {@code false} otherwise.
226 * @throws NullPointerException if the given array or one of it's element or
227 * the comparator is {@code null}.
228 */
229 public static <T> boolean isSorted(
230 final Seq<T> seq, final Comparator<? super T> comparator
231 ) {
232 boolean sorted = true;
233 for (int i = 0, n = seq.length() - 1; i < n && sorted; ++i) {
234 sorted = comparator.compare(seq.get(i), seq.get(i + 1)) <= 0;
235 }
236
237 return sorted;
238 }
239
240 /**
241 * Randomize the {@code array} using the given {@link Random} object. The used
242 * shuffling algorithm is from D. Knuth TAOCP, Seminumerical Algorithms,
243 * Third edition, page 142, Algorithm S (Selection sampling technique).
244 *
245 * @param array the {@code array} to randomize.
246 * @throws NullPointerException if the give array is {@code null}.
247 *
248 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
249 */
250 @Deprecated
251 public static <T> T[] shuffle(final T[] array) {
252 return shuffle(array, RandomRegistry.getRandom());
253 }
254
255 /**
256 * Randomize the {@code array} using the given {@link Random} object. The used
257 * shuffling algorithm is from D. Knuth TAOCP, Seminumerical Algorithms,
258 * Third edition, page 142, Algorithm S (Selection sampling technique).
259 *
260 * @param array the {@code array} to randomize.
261 * @param random the {@link Random} object to use for randomize.
262 * @param <T> the component type of the array to randomize.
263 * @throws NullPointerException if the give array or the random object is
264 * {@code null}.
265 *
266 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
267 */
268 @Deprecated
269 public static <T> T[] shuffle(final T[] array, final Random random) {
270 for (int j = array.length - 1; j > 0; --j) {
271 swap(array, j, random.nextInt(j + 1));
272 }
273
274 return array;
275 }
276
277 /**
278 * Randomize the {@code array} using the given {@link Random} object. The used
279 * shuffling algorithm is from D. Knuth TAOCP, Seminumerical Algorithms,
280 * Third edition, page 142, Algorithm S (Selection sampling technique).
281 *
282 * @param array the {@code array} to randomize.
283 * @throws NullPointerException if the give array is {@code null}.
284 *
285 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
286 */
287 @Deprecated
288 public static <T> MSeq<T> shuffle(final MSeq<T> array) {
289 return shuffle(array, RandomRegistry.getRandom());
290 }
291
292 /**
293 * Randomize the {@code array} using the given {@link Random} object. The used
294 * shuffling algorithm is from D. Knuth TAOCP, Seminumerical Algorithms,
295 * Third edition, page 142, Algorithm S (Selection sampling technique).
296 *
297 * @param array the {@code array} to randomize.
298 * @param random the {@link Random} object to use for randomize.
299 * @param <T> the component type of the array to randomize.
300 * @throws NullPointerException if the give array or the random object is
301 * {@code null}.
302 *
303 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
304 */
305 @Deprecated
306 public static <T> MSeq<T> shuffle(final MSeq<T> array, final Random random) {
307 for (int j = array.length() - 1; j > 0; --j) {
308 array.swap(j, random.nextInt(j + 1));
309 }
310
311 return array;
312 }
313
314 /**
315 * Randomize the {@code list} using the given {@link Random} object. The used
316 * shuffling algorithm is from D. Knuth TAOCP, Seminumerical Algorithms,
317 * Third edition, page 142, Algorithm S (Selection sampling technique).
318 *
319 * @param list the {@code array} to randomize.
320 * @param <T> the component type of the array to randomize.
321 * @throws NullPointerException if the give list is {@code null}.
322 *
323 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
324 */
325 @Deprecated
326 public static <T> void shuffle(final List<T> list) {
327 shuffle(list, RandomRegistry.getRandom());
328 }
329
330 /**
331 * Randomize the {@code list} using the given {@link Random} object. The used
332 * shuffling algorithm is from D. Knuth TAOCP, Seminumerical Algorithms,
333 * Third edition, page 142, Algorithm S (Selection sampling technique).
334 *
335 * @param list the {@code array} to randomize.
336 * @param random the {@link Random} object to use for randomize.
337 * @param <T> the component type of the array to randomize.
338 * @throws NullPointerException if the give list or the random object is
339 * {@code null}.
340 *
341 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
342 */
343 @Deprecated
344 public static <T> void shuffle(final List<T> list, final Random random) {
345 for (int j = list.size() - 1; j > 0; --j) {
346 swap(list, j, random.nextInt(j + 1));
347 }
348 }
349
350 /**
351 * Randomize the {@code array} using the given {@link Random} object. The used
352 * shuffling algorithm is from D. Knuth TAOCP, Seminumerical Algorithms,
353 * Third edition, page 142, Algorithm S (Selection sampling technique).
354 *
355 * @param array the {@code array} to randomize.
356 * @throws NullPointerException if the give array is {@code null}.
357 *
358 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
359 */
360 @Deprecated
361 public static void shuffle(final int[] array) {
362 shuffle(array, RandomRegistry.getRandom());
363 }
364
365 /**
366 * Randomize the {@code array} using the given {@link Random} object. The used
367 * shuffling algorithm is from D. Knuth TAOCP, Seminumerical Algorithms,
368 * Third edition, page 142, Algorithm S (Selection sampling technique).
369 *
370 * @param array the {@code array} to randomize.
371 * @param random the {@link Random} object to use for randomize.
372 * @throws NullPointerException if the give array or the random object is
373 * {@code null}.
374 *
375 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
376 */
377 @Deprecated
378 public static void shuffle(final int[] array, final Random random) {
379 for (int j = array.length - 1; j > 0; --j) {
380 swap(array, j, random.nextInt(j + 1));
381 }
382 }
383
384 /**
385 * Reverses the part of the array determined by the to indexes.
386 *
387 * @param <T> the array type.
388 * @param array the array to reverse
389 * @param from the first index (inclusive)
390 * @param to the second index (exclusive)
391 * @throws IllegalArgumentException if <tt>from > to</tt>
392 * @throws IndexOutOfBoundsException if <tt>from < 0</tt> or
393 * <tt>to > a.length</tt>
394 * @throws NullPointerException if the give array is {@code null}.
395 *
396 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
397 */
398 @Deprecated
399 public static <T> T[] reverse(final T[] array, final int from, final int to) {
400 rangeCheck(array.length, from, to);
401
402 int i = from;
403 int j = to;
404 while (i < j) {
405 swap(array, i++, --j);
406 }
407
408 return array;
409 }
410
411 /**
412 * Reverses the given array in place.
413 *
414 * @param <T> the array type.
415 * @param array the array to reverse.
416 * @throws NullPointerException if the give array is {@code null}.
417 *
418 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
419 */
420 @Deprecated
421 public static <T> T[] reverse(final T[] array) {
422 return reverse(array, 0, array.length);
423 }
424
425 @Deprecated
426 static void reverse(final byte[] array) {
427 int i = 0;
428 int j = array.length;
429 while (i < j) {
430 _swap(array, i++, --j);
431 }
432 }
433 private static void _swap(final byte[] array, final int i, final int j) {
434 final byte old = array[i];
435 array[i] = array[j];
436 array[j] = old;
437 }
438
439 private static void rangeCheck(int length, int from, int to) {
440 if (from > to) {
441 throw new IllegalArgumentException(
442 "fromIndex(" + from + ") > toIndex(" + to+ ")"
443 );
444 }
445 if (from < 0) {
446 throw new ArrayIndexOutOfBoundsException(from);
447 }
448 if (to > length) {
449 throw new ArrayIndexOutOfBoundsException(to);
450 }
451 }
452
453 /**
454 * Return a array with the indexes of the partitions of an array with the
455 * given size. The length of the returned array is {@code min(size, prts) + 1}.
456 * <p/>
457 * Some examples:
458 * <pre>
459 * partition(10, 3): [0, 3, 6, 10]
460 * partition(15, 6): [0, 2, 4, 6, 9, 12, 15]
461 * partition(5, 10): [0, 1, 2, 3, 4, 5]
462 * </pre>
463 *
464 * The following examples prints the start index (inclusive) and the end
465 * index (exclusive) of the {@code partition(15, 6)}.
466 * [code]
467 * int[] parts = partition(15, 6);
468 * for (int i = 0; i < parts.length - 1; ++i) {
469 * System.out.println(i + ": " + parts[i] + "\t" + parts[i + 1]);
470 * }
471 * [/code]
472 * <pre>
473 * 0: 0 2
474 * 1: 2 4
475 * 2: 4 6
476 * 3: 6 9
477 * 4: 9 12
478 * 5: 12 15
479 * </pre>
480 *
481 * This example shows how this can be used in an concurrent environment:
482 * [code]
483 * try (final Concurrency c = Concurrency.start()) {
484 * final int[] parts = arrays.partition(population.size(), _maxThreads);
485 *
486 * for (int i = 0; i < parts.length - 1; ++i) {
487 * final int part = i;
488 * c.execute(new Runnable() { @Override public void run() {
489 * for (int j = parts[part + 1]; --j >= parts[part];) {
490 * population.get(j).evaluate();
491 * }
492 * }});
493 * }
494 * }
495 * [/code]
496 *
497 * @param size the size of the array to partition.
498 * @param parts the number of parts the (virtual) array should be partitioned.
499 * @return the partition array with the length of {@code min(size, parts) + 1}.
500 * @throws IllegalArgumentException if {@code size} or {@code p} is less than one.
501 */
502 public static int[] partition(final int size, final int parts) {
503 if (size < 1) {
504 throw new IllegalArgumentException(
505 "Size must greater than zero: " + size
506 );
507 }
508 if (parts < 1) {
509 throw new IllegalArgumentException(
510 "Number of partitions must greater than zero: " + parts
511 );
512 }
513
514 final int pts = Math.min(size, parts);
515 final int[] partition = new int[pts + 1];
516
517 final int bulk = size/pts;
518 final int rest = size%pts;
519 assert ((bulk*pts + rest) == size);
520
521 for (int i = 0, n = pts - rest; i < n; ++i) {
522 partition[i] = i*bulk;
523 }
524 for (int i = 0, n = rest + 1; i < n; ++i) {
525 partition[pts - rest + i] = (pts - rest)*bulk + i*(bulk + 1);
526 }
527
528 return partition;
529 }
530
531 /**
532 * Selects a random subset of size {@code k} from a set of size {@code n}.
533 *
534 * @see #subset(int, int[])
535 *
536 * @param n the size of the set.
537 * @param k the size of the subset.
538 * @throws IllegalArgumentException if {@code n < k}, {@code k == 0} or if
539 * {@code n*k} will cause an integer overflow.
540 * @return the subset array.
541 *
542 * @deprecated Use {@link math#subset(int, int)} instead.
543 */
544 @Deprecated
545 public static int[] subset(final int n, final int k) {
546 return math.subset(n, k);
547 }
548
549 /**
550 * Selects a random subset of size {@code k} from a set of size {@code n}.
551 *
552 * @see #subset(int, int[], Random)
553 *
554 * @param n the size of the set.
555 * @param k the size of the subset.
556 * @param random the random number generator used.
557 * @throws NullPointerException if {@code random} is {@code null}.
558 * @throws IllegalArgumentException if {@code n < k}, {@code k == 0} or if
559 * {@code n*k} will cause an integer overflow.
560 * @return the subset array.
561 *
562 * @deprecated Use {@link math#subset(int, int, Random)} instead.
563 */
564 @Deprecated
565 public static int[] subset(final int n, final int k, final Random random) {
566 return math.subset(n, k, random);
567 }
568
569 /**
570 * <p>
571 * Selects a random subset of size {@code sub.length} from a set of size
572 * {@code n}.
573 * </p>
574 *
575 * <p>
576 * <em>Authors:</em>
577 * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This
578 * version based on the C++ version by John Burkardt.
579 * </p>
580 *
581 * <p><em><a href="https://people.scs.fsu.edu/~burkardt/c_src/subset/subset.html">
582 * Reference:</a></em>
583 * Albert Nijenhuis, Herbert Wilf,
584 * Combinatorial Algorithms for Computers and Calculators,
585 * Second Edition,
586 * Academic Press, 1978,
587 * ISBN: 0-12-519260-6,
588 * LC: QA164.N54.
589 * </p>
590 *
591 * @param n the size of the set.
592 * @param sub the sub set array.
593 * @throws NullPointerException if {@code sub} is {@code null}.
594 * @throws IllegalArgumentException if {@code n < sub.length},
595 * {@code sub.length == 0} or {@code n*sub.length} will cause an
596 * integer overflow.
597 *
598 * @deprecated Use {@link math#subset(int, int[])} instead.
599 */
600 @Deprecated
601 public static void subset(final int n, final int sub[]) {
602 math.subset(n, sub);
603 }
604
605 /**
606 * <p>
607 * Selects a random subset of size {@code sub.length} from a set of size
608 * {@code n}.
609 * </p>
610 *
611 * <p>
612 * <em>Authors:</em>
613 * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This
614 * version based on the C++ version by John Burkardt.
615 * </p>
616 *
617 * <p><em><a href="https://people.scs.fsu.edu/~burkardt/c_src/subset/subset.html">
618 * Reference:</a></em>
619 * Albert Nijenhuis, Herbert Wilf,
620 * Combinatorial Algorithms for Computers and Calculators,
621 * Second Edition,
622 * Academic Press, 1978,
623 * ISBN: 0-12-519260-6,
624 * LC: QA164.N54.
625 * </p>
626 *
627 * @param n the size of the set.
628 * @param sub the sub set array.
629 * @param random the random number generator used.
630 * @throws NullPointerException if {@code sub} or {@code random} is
631 * {@code null}.
632 * @throws IllegalArgumentException if {@code n < sub.length},
633 * {@code sub.length == 0} or {@code n*sub.length} will cause an
634 * integer overflow.
635 *
636 * @deprecated Use {@link math#subset(int, int[], Random)} instead.
637 */
638 @Deprecated
639 public static int[] subset(final int n, final int sub[], final Random random) {
640 return math.subset(n, sub, random);
641 }
642
643
644 /**
645 * Calculates a random permutation.
646 *
647 * @param p the permutation array.
648 * @throws NullPointerException if the permutation array is {@code null}.
649 *
650 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
651 */
652 @Deprecated
653 public static int[] permutation(final int[] p) {
654 return permutation(p, RandomRegistry.getRandom());
655 }
656
657 /**
658 * Calculates a random permutation.
659 *
660 * @param p the permutation array.
661 * @param random the random number generator.
662 * @throws NullPointerException if the permutation array or the random number
663 * generator is {@code null}.
664 *
665 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
666 */
667 @Deprecated
668 public static int[] permutation(final int[] p, final Random random) {
669 requireNonNull(p, "Permutation array");
670 requireNonNull(random, "Random");
671
672 for (int i = 0; i < p.length; ++i) {
673 p[i] = i;
674 }
675 shuffle(p, random);
676
677 return p;
678 }
679
680 /**
681 * Calculates the permutation with the given {@code rank}.
682 *
683 * <p>
684 * <em>Authors:</em>
685 * FORTRAN77 original version by Albert Nijenhuis, Herbert Wilf. This
686 * version based on the C++ version by John Burkardt.
687 * </p>
688 *
689 * <p><em><a href="https://people.scs.fsu.edu/~burkardt/c_src/subset/subset.html">
690 * Reference:</a></em>
691 * Albert Nijenhuis, Herbert Wilf,
692 * Combinatorial Algorithms for Computers and Calculators,
693 * Second Edition,
694 * Academic Press, 1978,
695 * ISBN: 0-12-519260-6,
696 * LC: QA164.N54.
697 * </p>
698 *
699 * @param p the permutation array.
700 * @param rank the permutation rank.
701 * @throws NullPointerException it the permutation array is {@code null}.
702 * @throws IllegalArgumentException if {@code rank < 1}.
703 *
704 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
705 */
706 @Deprecated
707 public static int[] permutation(final int[] p, final long rank) {
708 requireNonNull(p, "Permutation array");
709 if (rank < 1) {
710 throw new IllegalArgumentException(format(
711 "Rank smaler than 1: %s", rank
712 ));
713 }
714
715 Arrays.fill(p, 0);
716
717 long jrank = rank - 1;
718 for (int i = 1; i <= p.length; ++i) {
719 int iprev = p.length + 1 - i;
720 int irem = (int)(jrank%iprev);
721 jrank = jrank/iprev;
722
723 int j = 0;
724 int jdir = 0;
725 if ((jrank%2) == 1) {
726 j = 0;
727 jdir = 1;
728 } else {
729 j = p.length + 1;
730 jdir = -1;
731 }
732
733 int icount = 0;
734 do {
735 j = j + jdir;
736
737 if (p[j - 1] == 0) {
738 ++icount;
739 }
740 } while (irem >= icount);
741
742 p[j - 1] = iprev;
743 }
744
745 return p;
746 }
747
748 /**
749 * Returns the index of the first occurrence of the specified element in
750 * the {@code array}, or -1 if the {@code array} does not contain the element.
751 * @param array the array to search.
752 * @param start the start index of the search.
753 * @param element the element to search for.
754 * @return the index of the first occurrence of the specified element in the
755 * given {@code array}, of -1 if the {@code array} does not contain
756 * the element.
757 * @throws NullPointerException if the given {@code array} is {@code null}.
758 * @throws IndexOutOfBoundsException for an illegal end point index value
759 * (start < 0 || end > length || start > end)
760 *
761 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
762 */
763 @Deprecated
764 public static int indexOf(
765 final Object[] array, final int start, final int end,
766 final Object element
767 ) {
768 requireNonNull(array, "Array");
769 if (start < 0 || end > array.length || start > end) {
770 throw new IndexOutOfBoundsException(format(
771 "Invalid index range: [%d, %s]", start, end
772 ));
773 }
774
775 int index = -1;
776 if (element != null) {
777 for (int i = start; i < end && index == -1; ++i) {
778 if (element.equals(array[i])) {
779 index = i;
780 }
781 }
782 } else {
783 for (int i = start; i < end && index == -1; ++i) {
784 if (array[i] == null) {
785 index = i;
786 }
787 }
788 }
789
790 return index;
791 }
792
793
794 /**
795 * Returns the index of the first occurrence of the specified element in
796 * the {@code array}, or -1 if the {@code array} does not contain the element.
797 * @param array the array to search.
798 * @param element the element to search for.
799 * @return the index of the first occurrence of the specified element in the
800 * given {@code array}, of -1 if the {@code array} does not contain
801 * the element.
802 * @throws NullPointerException if the given {@code array} is {@code null}.
803 *
804 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
805 */
806 @Deprecated
807 public static int indexOf(final Object[] array, final Object element) {
808 return indexOf(array, 0, array.length, element);
809 }
810
811 /**
812 * @see #indexOf(Object[], Object)
813 *
814 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
815 */
816 @Deprecated
817 public static <T> int indexWhere(
818 final T[] array,
819 final Function<? super T, Boolean> predicate
820 ) {
821 requireNonNull(array, "Array");
822 requireNonNull(predicate, "Predicate");
823
824 int index = -1;
825
826 for (int i = 0; i < array.length && index == -1; ++i) {
827 if (predicate.apply(array[i])) {
828 index = i;
829 }
830 }
831
832 return index;
833 }
834
835 /**
836 * @see #indexOf(Object[], Object)
837 *
838 * @deprecated Not used in the <i>Jenetics</i> library. Will be removed.
839 */
840 @Deprecated
841 public static <T> int indexWhere(
842 final Iterable<? extends T> values,
843 final Function<? super T, Boolean> predicate
844 ) {
845 requireNonNull(values, "Array");
846 requireNonNull(predicate, "Predicate");
847
848 int index = -1;
849 int i = 0;
850 for (Iterator<? extends T>
851 it = values.iterator(); it.hasNext() && index == -1; ++i)
852 {
853 if (predicate.apply(it.next())) {
854 index = i;
855 }
856 }
857
858 return index;
859 }
860
861 /**
862 * @deprecated Align the naming with the upcomming JDK 1.8 release. Use
863 * {@link #forEach(Object[], Function)} instead.
864 */
865 @Deprecated
866 public static <T, R> void foreach(
867 final T[] array,
868 final Function<? super T, ? extends R> f
869 ) {
870 forEach(array, f);
871 }
872
873 /**
874 * Iterates over all elements of the given {@code array} as long as the
875 * {@code predicate} returns {@code true} (which means <i>continue</i>) and
876 * returns the index the iteration has been interrupted. -1 is returned if
877 * all elements were visited.
878 * <p/>
879 * Can be used to check all array elements for nullness.
880 *
881 * [code]
882 * public void foo(final Integer[] values) {
883 * arrays.forEach(values, new Validator.NonNull());
884 * ...
885 * }
886 * [/code]
887 *
888 * @param array the array to iterate.
889 * @param f the function to apply to every element.
890 * @throws NullPointerException if one of the elements are {@code null}.
891 */
892 public static <T, R> void forEach(
893 final T[] array,
894 final Function<? super T, ? extends R> f
895 ) {
896 requireNonNull(array, "Array");
897 requireNonNull(f, "Predicate");
898
899 for (int i = 0; i < array.length; ++i) {
900 f.apply(array[i]);
901 }
902 }
903
904 /**
905 * @deprecated Align the naming with the upcoming JDK 1.8 release. Use
906 * {@link #forEach(Iterable, Function)} instead.
907 */
908 @Deprecated
909 public static <T, R> void foreach(
910 final Iterable<? extends T> values,
911 final Function<? super T, ? extends R> f
912 ) {
913 forEach(values, f);
914 }
915
916 /**
917 * Iterates over all elements of the given {@code values}
918 *
919 * @param values the values to iterate.
920 * @param f the function to apply to each element.
921 * @throws NullPointerException if one of the elements are {@code null}.
922 */
923 public static <T, R> void forEach(
924 final Iterable<? extends T> values,
925 final Function<? super T, ? extends R> f
926 ) {
927 requireNonNull(values, "Array");
928 requireNonNull(f, "Function");
929
930 for (final T value : values) {
931 f.apply(value);
932 }
933 }
934
935
936 /**
937 * Map the array from type A to an other array of type B.
938 *
939 * @param <A> the source type.
940 * @param <B> the target type.
941 * @param a the source array.
942 * @param b the target array. If the given array is to short a new array
943 * with the right size is created, mapped and returned. If the given
944 * array is long enough <i>this</i> array is returned.
945 * @param converter the converter needed for mapping from type A to type B.
946 * @return the mapped array. If {@code b} is long enough {@code b} is
947 * returned otherwise a new created array.
948 * @throws NullPointerException if one of the arguments is {@code null}.
949 */
950 public static <A, B> B[] map(
951 final A[] a,
952 final B[] b,
953 final Function<? super A, ? extends B> converter
954 ) {
955 requireNonNull(a, "Source array");
956 requireNonNull(b, "Target array");
957 requireNonNull(converter, "Converter");
958
959 B[] result = b;
960 if (b.length < a.length) {
961 @SuppressWarnings("unchecked")
962 final B[] r = (B[])java.lang.reflect.Array.newInstance(
963 b.getClass().getComponentType(), a.length
964 );
965 result = r;
966 }
967
968 for (int i = 0; i < result.length; ++i) {
969 result[i] = converter.apply(a[i]);
970 }
971
972 return result;
973 }
974
975 }
|