/*
* $Id$
* This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc
*
* Copyright (c) 2000-2012 Stephane GALLAND.
* Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports,
* Universite de Technologie de Belfort-Montbeliard.
* Copyright (c) 2013-2016 The original authors, and other authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arakhne.afc.util;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Random;
import org.eclipse.xtext.xbase.lib.Inline;
import org.eclipse.xtext.xbase.lib.Pure;
import org.arakhne.afc.sizediterator.ArraySizedIterator;
import org.arakhne.afc.sizediterator.SizedIterator;
/**
* Some utilities functions for arrays.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@SuppressWarnings("checkstyle:methodcount")
public final class ArrayUtil {
private ArrayUtil() {
//
}
/** Reverse the specified array.
*
* @param <T> the type of the data in the array.
* @param tab the array.
*/
public static <T> void reverse(T[] tab) {
T tmp;
for (int i = 0; i < tab.length / 2; ++i) {
tmp = tab[i];
tab[i] = tab[tab.length - i - 1];
tab[tab.length - i - 1] = tmp;
}
}
/** Replies an array that corresponds to the given collection.
*
* @param <T> is the type of the elements.
* @param collection is the collection to translate
* @param clazz is the type of the elements.
* @return the array.
*/
@Pure
public static <T> T[] toArray(Collection<? extends T> collection, Class<T> clazz) {
final int size = (collection == null) ? 0 : collection.size();
final T[] tab = newInstance(clazz, size);
if ((collection != null) && (size > 0)) {
collection.toArray(tab);
}
return tab;
}
/** Replies an array that corresponds to the given collection.
*
* <p>This function clear the content of the given collection.
*
* @param <T> is the type of the elements.
* @param collection is the collection to translate
* @param clazz is the type of the elements.
* @return the array.
*/
public static <T> T[] toArrayAndClear(Collection<? extends T> collection, Class<T> clazz) {
final T[] tab = toArray(collection, clazz);
collection.clear();
return tab;
}
/** Merge the arrays.
*
* <p>This function does not remove the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param clazz is the type of the elements.
* @param arrays are the arrays to merge.
* @return the array.
*/
@Pure
public static <T> T[] merge(Class<T> clazz, @SuppressWarnings("unchecked") T[]... arrays) {
int length = 0;
for (final T[] tab : arrays) {
if (tab != null) {
length += tab.length;
}
}
final T[] result = newInstance(clazz, length);
int i = 0;
for (final T[] tab : arrays) {
if (tab != null) {
System.arraycopy(tab, 0, result, i, tab.length);
i += tab.length;
}
}
return result;
}
/** Merge the elements to make an array.
*
* <p>This function does not remove the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param clazz is the type of the elements.
* @param elements are the elements to merge.
* @return the array.
*/
@Pure
public static <T> T[] merge(Class<T> clazz, @SuppressWarnings("unchecked") T... elements) {
final T[] result = newInstance(clazz, elements.length);
System.arraycopy(elements, 0, result, 0, elements.length);
return result;
}
/** Merge the elements to make an array.
*
* <p>This function does not remove the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param source is the first array to merge.
* @param clazz is the type of the elements.
* @param elements are the elements to merge.
* @return the array.
*/
@Pure
public static <T> T[] merge(Class<T> clazz, T[] source, @SuppressWarnings("unchecked") T... elements) {
final T[] result = newInstance(clazz, source.length + elements.length);
System.arraycopy(source, 0, result, 0, source.length);
System.arraycopy(elements, 0, result, source.length, elements.length);
return result;
}
/** Merge the arrays.
*
* <p>This function removes the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param clazz is the type of the elements.
* @param arrays are the arrays to merge.
* @return the array.
* @deprecated see {@link #mergeWithoutNull(Class, Object[]...)}
*/
@Pure
@Inline(value = "ArrayUtil.mergeWithoutNull($1, $2)", imported = {ArrayUtil.class})
@SuppressWarnings("all")
@Deprecated
public static <T> T[] merge_without_null(Class<T> clazz, T[]... arrays) {
return mergeWithoutNull(clazz, arrays);
}
/** Merge the elements to make an array.
*
* <p>This function removes the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param clazz is the type of the elements.
* @param elements are the elements to merge.
* @return the array.
* @deprecated see {@link #mergeWithoutNull(Class, Object...)}
*/
@Pure
@Inline(value = "ArrayUtil.mergeWithoutNull($1, $2)", imported = {ArrayUtil.class})
@SuppressWarnings("all")
@Deprecated
public static <T> T[] merge_without_null(Class<T> clazz, T... elements) {
return mergeWithoutNull(clazz, elements);
}
/** Merge the elements to make an array.
*
* <p>This function removes the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param source is the first array to merge.
* @param clazz is the type of the elements.
* @param elements are the elements to merge.
* @return the array.
* @deprecated see {@link #mergeWithoutNull(Class, Object[], Object...)}
*/
@Pure
@Inline(value = "ArrayUtil.mergeWithoutNull($1, $2, $3)", imported = {ArrayUtil.class})
@SuppressWarnings("all")
@Deprecated
public static <T> T[] merge_without_null(Class<T> clazz, T[] source, T... elements) {
return mergeWithoutNull(clazz, source, elements);
}
/** Merge the arrays.
*
* <p>This function removes the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param clazz is the type of the elements.
* @param arrays are the arrays to merge.
* @return the array.
*/
@Pure
public static <T> T[] mergeWithoutNull(Class<T> clazz, @SuppressWarnings("unchecked") T[]... arrays) {
int length = 0;
for (final T[] tab : arrays) {
if (tab != null) {
for (final T t : tab) {
if (t != null) {
++length;
}
}
}
}
final T[] result = newInstance(clazz, length);
int i = 0;
for (final T[] tab : arrays) {
if (tab != null) {
for (final T t : tab) {
if (t != null) {
result[i] = t;
++i;
}
}
}
}
return result;
}
/** Merge the elements to make an array.
*
* <p>This function removes the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param clazz is the type of the elements.
* @param elements are the elements to merge.
* @return the array.
*/
@Pure
public static <T> T[] mergeWithoutNull(Class<T> clazz, @SuppressWarnings("unchecked") T... elements) {
int nbNotNull = 0;
for (final T t : elements) {
if (t != null) {
++nbNotNull;
}
}
final T[] result = newInstance(clazz, nbNotNull);
int i = 0;
for (final T t : elements) {
if (t != null) {
result[i++] = t;
}
}
return result;
}
/** Merge the elements to make an array.
*
* <p>This function removes the <code>null</code> values.
*
* @param <T> is the type of the elements.
* @param source is the first array to merge.
* @param clazz is the type of the elements.
* @param elements are the elements to merge.
* @return the array.
*/
@Pure
public static <T> T[] mergeWithoutNull(Class<T> clazz, T[] source, @SuppressWarnings("unchecked") T... elements) {
int nbNotNull = 0;
for (final T t : source) {
if (t != null) {
++nbNotNull;
}
}
for (final T t : elements) {
if (t != null) {
++nbNotNull;
}
}
final T[] result = newInstance(clazz, nbNotNull);
int i = 0;
for (final T t : source) {
if (t != null) {
result[i++] = t;
}
}
for (final T t : elements) {
if (t != null) {
result[i++] = t;
}
}
return result;
}
/** Remove the given elements from the array.
*
* @param <T> is the type of the elements.
* @param clazz is the type of the elements.
* @param source is the array to scan
* @param toRemove are the elements to remove.
* @return the array without the removed elements.
*/
@Pure
public static <T> T[] removeElements(Class<T> clazz, T[] source, @SuppressWarnings("unchecked") T... toRemove) {
final List<T> list = new ArrayList<>();
list.addAll(Arrays.asList(source));
for (final T t : toRemove) {
list.remove(t);
}
return toArrayAndClear(list, clazz);
}
/** Cast the specified array and put <code>null</code> is the array when
* the element could not be casted.
*
* @param <I> is the type of the elements before the cast.
* @param <T> is the type of the elements after the cast.
* @param originalArray is the array to cast
* @param clazz is the casting type
* @return the array in which each element was casted according to the given type.
* @see #castRestrictedArray(Object[], Class)
*/
@Pure
public static <I, T> T[] castArray(I[] originalArray, Class<T> clazz) {
final int size = (originalArray == null) ? 0 : originalArray.length;
final T[] result = newInstance(clazz, size);
if ((originalArray != null) && (size > 0)) {
int index = 0;
for (final I to : originalArray) {
result[index] = (clazz.isInstance(to)) ? clazz.cast(to) : null;
++index;
}
}
return result;
}
/** Cast the specified array and put <code>null</code> is the array when
* the element could not be casted.
*
* @param <I> is the type of the elements before the cast.
* @param <O> is the type of the elements after the cast.
* @param originalArray is the array to cast
* @param clazz is the casting type
* @return the array in which each element was casted according to the given type.
* @see #castRestrictedArray(Object[], Class)
*/
@Pure
public static <I, O> O[] castArray(Collection<I> originalArray, Class<O> clazz) {
final int size = (originalArray == null) ? 0 : originalArray.size();
final O[] result = newInstance(clazz, size);
if ((originalArray != null) && (size > 0)) {
int index = 0;
for (final I to : originalArray) {
result[index] = (clazz.isInstance(to)) ? clazz.cast(to) : null;
++index;
}
}
return result;
}
/** Replies an array in which all the elements must
* respect the given comparator.
*
* <p>The respect of the comparator is done when the
* comparator replies equals.
*
* @param <T> is the type of the elements
* @param originalArray is the array to cast
* @param clazz is the casting type
* @param comparator is filtering the elements.
* @return the array in which each element was casted according to the given type.
*/
@Pure
public static <T> T[] restrictArray(T[] originalArray, Class<T> clazz, Filter<T> comparator) {
final int size = (originalArray == null) ? 0 : originalArray.length;
final List<T> result = new ArrayList<>();
if ((originalArray != null) && (size > 0)) {
for (final T to : originalArray) {
if (comparator.filter(to)) {
result.add(to);
}
}
}
return toArrayAndClear(result, clazz);
}
/** Cast the specified array and remove the elements that could not be casted.
*
* @param <I> is the type of the elements before the cast.
* @param <O> is the type of the elements after the cast.
* @param originalArray is the array to cast
* @param clazz is the casting type
* @return the array in which each element was casted according to the given type.
* @see #castArray(Object[], Class)
*/
@SuppressWarnings("unchecked")
@Pure
public static <I, O> O[] castRestrictedArray(I[] originalArray, Class<O> clazz) {
final int size = (originalArray == null) ? 0 : originalArray.length;
final List<O> result = new ArrayList<>();
if ((originalArray != null) && (size > 0)) {
for (final I to : originalArray) {
if (clazz.isInstance(to)) {
result.add((O) to);
}
}
}
return toArrayAndClear(result, clazz);
}
/** Cast the specified array and remove the elements that could not be casted.
*
* @param <I> is the type of the elements before the cast.
* @param <O> is the type of the elements after the cast.
* @param originalArray is the array to cast
* @param clazz is the casting type
* @return the array in which each element was casted according to the given type.
* @see #castArray(Object[], Class)
*/
@SuppressWarnings("unchecked")
@Pure
public static <I, O> O[] castRestrictedArray(Collection<I> originalArray, Class<O> clazz) {
final int size = (originalArray == null) ? 0 : originalArray.size();
final ArrayList<O> result = new ArrayList<>();
if ((originalArray != null) && (size > 0)) {
for (final I to : originalArray) {
if (clazz.isInstance(to)) {
result.add((O) to);
}
}
}
return toArrayAndClear(result, clazz);
}
/** Replies of the given element is in the array.
*
* <p>This function does not call {@link Object#equals(java.lang.Object)}.
* It tests the equality on the object references.
*
* @param <T> is the type of the elements.
* @param elt is the element to search for.
* @param array is the array inside which the search must be done.
* @return <code>true</code> if the element is inside the array, otherwise <code>false</code>
*/
@Pure
public static <T> boolean containsObject(T elt, T[] array) {
for (final T t : array) {
if (t == elt) {
return true;
}
}
return false;
}
/** Replies of the given element is in the array.
*
* <p>This function does not call {@link Object#equals(java.lang.Object)}.
* It tests the equality on the object references.
*
* @param <T> is the type of the elements.
* @param elts are the elements to search for.
* @param array is the array inside which the search must be done.
* @return <code>true</code> if the elements are inside the array, otherwise <code>false</code>
*/
@Pure
public static <T> boolean containsAllObjects(T[] elts, T[] array) {
boolean found;
for (final T elt : elts) {
found = false;
for (final T t : array) {
if (t == elt) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
/** Replies of the given element is in the array.
*
* <p>This function is based on {@link Object#equals(java.lang.Object)}.
*
* @param <T> is the type of the elements.
* @param elt is the element to search for.
* @param array is the array inside which the search must be done.
* @return <code>true</code> if the element is inside the array, otherwise <code>false</code>
*/
@Pure
public static <T> boolean contains(T elt, @SuppressWarnings("unchecked") T... array) {
for (final T t : array) {
if ((t == elt) || ((t != null) && (t.equals(elt)))) {
return true;
}
}
return false;
}
/** Replies of the given element is in the sorted array.
*
* <p>This function assumes that the given array is sorted
* according to the given comparator.
* A dichotomic algorithm is used.
*
* @param <T> is the type of the elements.
* @param comparator is the comparator used to sort the array.
* @param elt is the element to search for.
* @param array is the array inside which the search must be done.
* @return <code>true</code> if the element is inside the array, otherwise <code>false</code>
* @since 4.0
*/
@Pure
public static <T> boolean contains(Comparator<T> comparator, T elt, @SuppressWarnings("unchecked") T... array) {
assert comparator != null;
assert elt != null;
assert array != null;
int first = 0;
int last = array.length - 1;
int center;
int cmp;
T indata;
while (last >= first) {
center = (first + last) / 2;
indata = array[center];
cmp = comparator.compare(elt, indata);
if (cmp == 0) {
return true;
} else if (cmp < 0) {
last = center - 1;
} else {
first = center + 1;
}
}
return false;
}
/** Replies if the given elements is in the array.
*
* <p>This function is based on {@link Object#equals(java.lang.Object)}.
*
* @param <T> is the type of the elements.
* @param elts are the elements to search for.
* @param array is the array inside which the search must be done.
* @return <code>true</code> if the elements are inside the array, otherwise <code>false</code>
*/
@Pure
public static <T> boolean containsAll(T[] elts, T[] array) {
boolean found;
for (final T elt : elts) {
found = false;
for (final T t : array) {
if ((t == elt) || ((t != null) && (t.equals(elt)))) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
/** Replies of one of the given elements is in the array.
*
* <p>This function is based on {@link Object#equals(java.lang.Object)}.
*
* @param <T> is the type of the elements.
* @param elts is the first array.
* @param array is the second array.
* @return <code>true</code> if an intersection is existing, otherwise <code>false</code>
*/
@Pure
public static <T> boolean intersects(T[] elts, T[] array) {
for (final T t : array) {
for (final T elt : elts) {
if ((elt == t) || ((t != null) && (t.equals(elt)))) {
return true;
}
}
}
return false;
}
/** Create an instance of array.
*
* @param <T> is the type of the elements.
* @param clazz is the type of the elements.
* @param size is the size of the new array.
* @return the new array.
*/
@Pure
@SuppressWarnings("unchecked")
public static <T> T[] newInstance(Class<T> clazz, int size) {
if (size < 0) {
throw new IndexOutOfBoundsException(size + "<0"); //$NON-NLS-1$
}
return (T[]) Array.newInstance(clazz, size);
}
/** Shuffle the specified array.
*
* @param <T> is the type of the elements.
* @param array is the array to shuffle.
*/
@Pure
@Inline(value = "ArrayUtil.shuffle($1, new Random())", imported = {ArrayUtil.class, Random.class},
statementExpression = true)
public static <T> void shuffle(T[] array) {
shuffle(array, new Random());
}
/** Shuffle the specified array.
*
* @param <T> is the type of the elements.
* @param array is the array to shuffle.
* @param rnd is the random number generator to use.
*/
@Pure
public static <T> void shuffle(T[] array, Random rnd) {
int ir;
T tmp;
for (int i = array.length; i > 1; --i) {
ir = rnd.nextInt(i);
tmp = array[i - 1];
array[i - 1] = array[ir];
array[ir] = tmp;
}
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
*/
@Pure
@Inline(value = "ArrayUtil.shuffle($1, new Random())", imported = {ArrayUtil.class, Random.class},
statementExpression = true)
public static void shuffle(boolean[] array) {
shuffle(array, new Random());
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
* @param rnd is the random number generator to use.
*/
@Pure
public static void shuffle(boolean[] array, Random rnd) {
int ir;
boolean tmp;
for (int i = array.length; i > 1; --i) {
ir = rnd.nextInt(i);
tmp = array[i - 1];
array[i - 1] = array[ir];
array[ir] = tmp;
}
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
*/
@Pure
@Inline(value = "ArrayUtil.shuffle($1, new Random())", imported = {ArrayUtil.class, Random.class},
statementExpression = true)
public static void shuffle(byte[] array) {
shuffle(array, new Random());
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
* @param rnd is the random number generator to use.
*/
@Pure
public static void shuffle(byte[] array, Random rnd) {
int ir;
byte tmp;
for (int i = array.length; i > 1; --i) {
ir = rnd.nextInt(i);
tmp = array[i - 1];
array[i - 1] = array[ir];
array[ir] = tmp;
}
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
*/
@Pure
@Inline(value = "ArrayUtil.shuffle($1, new Random())", imported = {ArrayUtil.class, Random.class},
statementExpression = true)
public static void shuffle(char[] array) {
shuffle(array, new Random());
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
* @param rnd is the random number generator to use.
*/
@Pure
public static void shuffle(char[] array, Random rnd) {
int ir;
char tmp;
for (int i = array.length; i > 1; --i) {
ir = rnd.nextInt(i);
tmp = array[i - 1];
array[i - 1] = array[ir];
array[ir] = tmp;
}
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
*/
@Pure
@Inline(value = "ArrayUtil.shuffle($1, new Random())", imported = {ArrayUtil.class, Random.class},
statementExpression = true)
public static void shuffle(int[] array) {
shuffle(array, new Random());
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
* @param rnd is the random number generator to use.
*/
@Pure
public static void shuffle(int[] array, Random rnd) {
int ir;
int tmp;
for (int i = array.length; i > 1; --i) {
ir = rnd.nextInt(i);
tmp = array[i - 1];
array[i - 1] = array[ir];
array[ir] = tmp;
}
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
*/
@Pure
@Inline(value = "ArrayUtil.shuffle($1, new Random())", imported = {ArrayUtil.class, Random.class},
statementExpression = true)
public static void shuffle(long[] array) {
shuffle(array, new Random());
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
* @param rnd is the random number generator to use.
*/
@Pure
public static void shuffle(long[] array, Random rnd) {
int ir;
long tmp;
for (int i = array.length; i > 1; --i) {
ir = rnd.nextInt(i);
tmp = array[i - 1];
array[i - 1] = array[ir];
array[ir] = tmp;
}
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
*/
@Pure
@Inline(value = "ArrayUtil.shuffle($1, new Random())", imported = {ArrayUtil.class, Random.class},
statementExpression = true)
public static void shuffle(float[] array) {
shuffle(array, new Random());
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
* @param rnd is the random number generator to use.
*/
@Pure
public static void shuffle(float[] array, Random rnd) {
int ir;
float tmp;
for (int i = array.length; i > 1; --i) {
ir = rnd.nextInt(i);
tmp = array[i - 1];
array[i - 1] = array[ir];
array[ir] = tmp;
}
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
*/
@Pure
@Inline(value = "ArrayUtil.shuffle($1, new Random())", imported = {ArrayUtil.class, Random.class},
statementExpression = true)
public static void shuffle(double[] array) {
shuffle(array, new Random());
}
/** Shuffle the specified array.
*
* @param array is the array to shuffle.
* @param rnd is the random number generator to use.
*/
@Pure
public static void shuffle(double[] array, Random rnd) {
int ir;
double tmp;
for (int i = array.length; i > 1; --i) {
ir = rnd.nextInt(i);
tmp = array[i - 1];
array[i - 1] = array[ir];
array[ir] = tmp;
}
}
/**
* Replies a string representation of the given object.
*
* <p>This function supports the base type's arrays.
*
* @param obj is the object to translate.
* @return a string representation of the given object.
*/
@Pure
@SuppressWarnings({"checkstyle:returncount", "checkstyle:npathcomplexity"})
public static String toString(Object obj) {
if (obj == null) {
return null;
}
if (obj instanceof boolean[]) {
return Arrays.toString((boolean[]) obj);
}
if (obj instanceof byte[]) {
return Arrays.toString((byte[]) obj);
}
if (obj instanceof char[]) {
return Arrays.toString((char[]) obj);
}
if (obj instanceof short[]) {
return Arrays.toString((short[]) obj);
}
if (obj instanceof int[]) {
return Arrays.toString((int[]) obj);
}
if (obj instanceof long[]) {
return Arrays.toString((long[]) obj);
}
if (obj instanceof float[]) {
return Arrays.toString((float[]) obj);
}
if (obj instanceof double[]) {
return Arrays.toString((double[]) obj);
}
if (obj instanceof Object[]) {
return Arrays.toString((Object[]) obj);
}
return obj.toString();
}
/** Replies a sized iterator on the objects.
*
* @param <T> is the type of the object to iterate on.
* @param array are the objects to iterate on.
* @return an iterator
*/
@Pure
@Inline(value = "new ArraySizedIterator<>($1)", imported = {ArraySizedIterator.class})
public static <T> SizedIterator<T> sizedIterator(T[] array) {
return new ArraySizedIterator<>(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static SizedIterator<Character> sizedIterator(char[] array) {
return new NativeCharacterToObjectCharacterIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static SizedIterator<Byte> sizedIterator(byte[] array) {
return new NativeByteToObjectByteIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static SizedIterator<Short> sizedIterator(short[] array) {
return new NativeShortToObjectShortIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static SizedIterator<Integer> sizedIterator(int[] array) {
return new NativeIntegerToObjectIntegerIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static SizedIterator<Long> sizedIterator(long[] array) {
return new NativeLongToObjectLongIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static SizedIterator<Float> sizedIterator(float[] array) {
return new NativeFloatToObjectFloatIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static SizedIterator<Double> sizedIterator(double[] array) {
return new NativeDoubleToObjectDoubleIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static SizedIterator<Boolean> sizedIterator(boolean[] array) {
return new NativeBooleanToObjectBooleanIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param <T> is the type of the object to iterate on.
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
@Inline(value = "new ArraySizedIterator<>($1)", imported = {ArraySizedIterator.class})
public static <T> Iterator<T> iterator(T[] array) {
return new ArraySizedIterator<>(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static Iterator<Boolean> iterator(boolean[] array) {
return new NativeBooleanToObjectBooleanIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static Iterator<Character> iterator(char[] array) {
return new NativeCharacterToObjectCharacterIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static Iterator<Byte> iterator(byte[] array) {
return new NativeByteToObjectByteIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static Iterator<Short> iterator(short[] array) {
return new NativeShortToObjectShortIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static Iterator<Integer> iterator(int[] array) {
return new NativeIntegerToObjectIntegerIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static Iterator<Long> iterator(long[] array) {
return new NativeLongToObjectLongIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static Iterator<Float> iterator(float[] array) {
return new NativeFloatToObjectFloatIterator(array);
}
/** Replies a sized iterator on the objects.
*
* @param array are the objects to iterate on.
* @return an iterator
* @since 4.1
*/
@Pure
public static Iterator<Double> iterator(double[] array) {
return new NativeDoubleToObjectDoubleIterator(array);
}
/**
* Some utilities functions for arrays.
*
* @param <T> is the type of the value to pass to the filter.
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@FunctionalInterface
public interface Filter<T> {
/** Filtering the objects.
*
* @param obj is the value to filter.
* @return <code>true</code> if the given value is acceptable, otherwise <code>false</code>
*/
@Pure
boolean filter(T obj);
}
/** Autoboxing iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavenartifactid $ArtifactId$
* @mavengroupid $GroupId$
*/
private static class NativeBooleanToObjectBooleanIterator implements SizedIterator<Boolean> {
private final boolean[] array;
private int idx;
/** Construct the iterator.
*
* @param data the data.
*/
NativeBooleanToObjectBooleanIterator(boolean[] data) {
this.array = data;
}
@Override
public boolean hasNext() {
return this.array != null && this.idx >= 0 && this.idx < this.array.length;
}
@Override
public Boolean next() {
if (this.array != null && this.idx >= 0 && this.idx < this.array.length) {
final Boolean b = Boolean.valueOf(this.array[this.idx]);
++this.idx;
return b;
}
throw new NoSuchElementException();
}
@Override
public int totalSize() {
return this.array == null ? 0 : this.array.length;
}
@Override
public int index() {
return this.idx - 1;
}
@Override
public int rest() {
return totalSize() - (index() + 1);
}
}
/** Autoboxing iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavenartifactid $ArtifactId$
* @mavengroupid $GroupId$
*/
private static class NativeCharacterToObjectCharacterIterator implements SizedIterator<Character> {
private final char[] array;
private int idx;
/** Construct iterator.
*
* @param data the data.
*/
NativeCharacterToObjectCharacterIterator(char[] data) {
this.array = data;
}
@Override
public boolean hasNext() {
return this.array != null && this.idx >= 0 && this.idx < this.array.length;
}
@Override
public Character next() {
if (this.array != null && this.idx >= 0 && this.idx < this.array.length) {
final Character c = Character.valueOf(this.array[this.idx]);
++this.idx;
return c;
}
throw new NoSuchElementException();
}
@Override
public int totalSize() {
return this.array == null ? 0 : this.array.length;
}
@Override
public int index() {
return this.idx - 1;
}
@Override
public int rest() {
return totalSize() - (index() + 1);
}
}
/** Autoboxing iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavenartifactid $ArtifactId$
* @mavengroupid $GroupId$
*/
private static class NativeByteToObjectByteIterator implements SizedIterator<Byte> {
private final byte[] array;
private int idx;
/** Construct the iterator.
*
* @param data the data.
*/
NativeByteToObjectByteIterator(byte[] data) {
this.array = data;
}
@Override
public boolean hasNext() {
return this.array != null && this.idx >= 0 && this.idx < this.array.length;
}
@Override
public Byte next() {
if (this.array != null && this.idx >= 0 && this.idx < this.array.length) {
final Byte b = Byte.valueOf(this.array[this.idx]);
++this.idx;
return b;
}
throw new NoSuchElementException();
}
@Override
public int totalSize() {
return this.array == null ? 0 : this.array.length;
}
@Override
public int index() {
return this.idx - 1;
}
@Override
public int rest() {
return totalSize() - (index() + 1);
}
}
/** Autoboxing iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavenartifactid $ArtifactId$
* @mavengroupid $GroupId$
*/
private static class NativeShortToObjectShortIterator implements SizedIterator<Short> {
private final short[] array;
private int idx;
/** Construct the iterator.
*
* @param data the data.
*/
NativeShortToObjectShortIterator(short[] data) {
this.array = data;
}
@Override
public boolean hasNext() {
return this.array != null && this.idx >= 0 && this.idx < this.array.length;
}
@Override
public Short next() {
if (this.array != null && this.idx >= 0 && this.idx < this.array.length) {
final Short s = Short.valueOf(this.array[this.idx]);
++this.idx;
return s;
}
throw new NoSuchElementException();
}
@Override
public int totalSize() {
return this.array == null ? 0 : this.array.length;
}
@Override
public int index() {
return this.idx - 1;
}
@Override
public int rest() {
return totalSize() - (index() + 1);
}
}
/** Autoboxing iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavenartifactid $ArtifactId$
* @mavengroupid $GroupId$
*/
private static class NativeIntegerToObjectIntegerIterator implements SizedIterator<Integer> {
private final int[] array;
private int idx;
/** Construct the iterator.
*
* @param data the data.
*/
NativeIntegerToObjectIntegerIterator(int[] data) {
this.array = data;
}
@Override
public boolean hasNext() {
return this.array != null && this.idx >= 0 && this.idx < this.array.length;
}
@Override
public Integer next() {
if (this.array != null && this.idx >= 0 && this.idx < this.array.length) {
final Integer f = Integer.valueOf(this.array[this.idx]);
++this.idx;
return f;
}
throw new NoSuchElementException();
}
@Override
public int totalSize() {
return this.array == null ? 0 : this.array.length;
}
@Override
public int index() {
return this.idx - 1;
}
@Override
public int rest() {
return totalSize() - (index() + 1);
}
}
/** Autoboxing iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavenartifactid $ArtifactId$
* @mavengroupid $GroupId$
*/
private static class NativeLongToObjectLongIterator implements SizedIterator<Long> {
private final long[] array;
private int idx;
/** Construct iterator.
*
* @param data the data.
*/
NativeLongToObjectLongIterator(long[] data) {
this.array = data;
}
@Override
public boolean hasNext() {
return this.array != null && this.idx >= 0 && this.idx < this.array.length;
}
@Override
public Long next() {
if (this.array != null && this.idx >= 0 && this.idx < this.array.length) {
final Long l = Long.valueOf(this.array[this.idx]);
++this.idx;
return l;
}
throw new NoSuchElementException();
}
@Override
public int totalSize() {
return this.array == null ? 0 : this.array.length;
}
@Override
public int index() {
return this.idx - 1;
}
@Override
public int rest() {
return totalSize() - (index() + 1);
}
}
/** Autoboxing iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavenartifactid $ArtifactId$
* @mavengroupid $GroupId$
*/
private static class NativeFloatToObjectFloatIterator implements SizedIterator<Float> {
private final float[] array;
private int idx;
/** Construct iterator.
*
* @param data the data.
*/
NativeFloatToObjectFloatIterator(float[] data) {
this.array = data;
}
@Override
public boolean hasNext() {
return this.array != null && this.idx >= 0 && this.idx < this.array.length;
}
@Override
public Float next() {
if (this.array != null && this.idx >= 0 && this.idx < this.array.length) {
final Float f = Float.valueOf(this.array[this.idx]);
++this.idx;
return f;
}
throw new NoSuchElementException();
}
@Override
public int totalSize() {
return this.array == null ? 0 : this.array.length;
}
@Override
public int index() {
return this.idx - 1;
}
@Override
public int rest() {
return totalSize() - (index() + 1);
}
}
/** Autoboxing iterator.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavenartifactid $ArtifactId$
* @mavengroupid $GroupId$
*/
private static class NativeDoubleToObjectDoubleIterator implements SizedIterator<Double> {
private final double[] array;
private int idx;
/** Construct the iterator.
*
* @param data the data.
*/
NativeDoubleToObjectDoubleIterator(double[] data) {
this.array = data;
}
@Override
public boolean hasNext() {
return this.array != null && this.idx >= 0 && this.idx < this.array.length;
}
@Override
public Double next() {
if (this.array != null && this.idx >= 0 && this.idx < this.array.length) {
final Double d = Double.valueOf(this.array[this.idx]);
++this.idx;
return d;
}
throw new NoSuchElementException();
}
@Override
public int totalSize() {
return this.array == null ? 0 : this.array.length;
}
@Override
public int index() {
return this.idx - 1;
}
@Override
public int rest() {
return totalSize() - (index() + 1);
}
}
}