/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2001-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.resources;
import java.lang.reflect.Array;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.util.Comparator;
import java.util.Locale;
import org.geotools.util.Utilities;
/**
* Simple operations on arrays. This class provides a central place for
* inserting and deleting elements in an array, as well as resizing the array.
* This class may be removed if JavaSoft provide some language construct
* functionally equivalent to C/C++'s {@code realloc}.
*
* @since 2.0
* @source $URL$
* @version $Id$
* @author Martin Desruisseaux (IRD)
*
* @todo Replace all {@code resize} methods by {@code Arrays.copyOf} when we will be allowed to
* compile for Java 6.
*/
public final class XArray {
/**
* All object constructions of this class are forbidden.
*/
private XArray() {
}
/**
* Returns an array containing the same elements as the given {@code array} but with the
* specified {@code length}, truncating or padding with {@code null} if necessary.
* <ul>
* <li><p>If the given {@code length} is longer than the length of the given {@code array},
* then the returned array will contain all the elements of {@code array} at index
* <var>i</var> < {@code array.length}. Elements at index <var>i</var> >=
* {@code array.length} are initialized to {@code null}.</p></li>
*
* <li><p>If the given {@code length} is shorter than the length of the given {@code array},
* then the returned array will contain only the elements of {@code array} at index
* <var>i</var> < {@code length}. Remainding elements are not copied.</p></li>
*
* <li><p>If the given {@code length} is equals to the length of the given {@code array},
* then {@code array} is returned unchanged. <strong>No copy</strong> is performed.
* This behavior is what make this method different than {@link Arrays#copyOf}.</p></li>
*
* @param <T> The array elements.
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*
* @see Arrays#copyOf(Object[],int)
*/
private static <T> T doResize(final T array, final int length) {
final int current = array == null ? 0 : Array.getLength(array);
if (current != length) {
@SuppressWarnings("unchecked")
final T newArray = (T) Array.newInstance(array.getClass().getComponentType(), length);
System.arraycopy(array, 0, newArray, 0, Math.min(current, length));
return newArray;
} else {
return array;
}
}
/**
* Returns an array containing the same elements as the given {@code array} but with the
* specified {@code length}, truncating or padding with {@code null} if necessary.
* <ul>
* <li><p>If the given {@code length} is longer than the length of the given {@code array},
* then the returned array will contain all the elements of {@code array} at index
* <var>i</var> < {@code array.length}. Elements at index <var>i</var> >=
* {@code array.length} are initialized to {@code null}.</p></li>
*
* <li><p>If the given {@code length} is shorter than the length of the given {@code array},
* then the returned array will contain only the elements of {@code array} at index
* <var>i</var> < {@code length}. Remainding elements are not copied.</p></li>
*
* <li><p>If the given {@code length} is equals to the length of the given {@code array},
* then {@code array} is returned unchanged. <strong>No copy</strong> is performed.
* This behavior is what make this method different than {@link Arrays#copyOf}.</p></li>
*
* @param <E> The array elements.
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*
* @see Arrays#copyOf(Object[],int)
*/
public static <E> E[] resize(final E[] array, final int length) {
return doResize(array, length);
}
/**
* Returns an array containing the same elements as the given {@code array} but
* specified {@code length}, truncating or padding with zeros if necessary.
*
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*/
public static double[] resize(final double[] array, final int length) {
return doResize(array, length);
}
/**
* Returns an array containing the same elements as the given {@code array} but
* specified {@code length}, truncating or padding with zeros if necessary.
*
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*/
public static float[] resize(final float[] array, final int length) {
return doResize(array, length);
}
/**
* Returns an array containing the same elements as the given {@code array} but
* specified {@code length}, truncating or padding with zeros if necessary.
*
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*/
public static long[] resize(final long[] array, final int length) {
return doResize(array, length);
}
/**
* Returns an array containing the same elements as the given {@code array} but
* specified {@code length}, truncating or padding with zeros if necessary.
*
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*/
public static int[] resize(final int[] array, final int length) {
return doResize(array, length);
}
/**
* Returns an array containing the same elements as the given {@code array} but
* specified {@code length}, truncating or padding with zeros if necessary.
*
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*/
public static short[] resize(final short[] array, final int length) {
return doResize(array, length);
}
/**
* Returns an array containing the same elements as the given {@code array} but
* specified {@code length}, truncating or padding with zeros if necessary.
*
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*/
public static byte[] resize(final byte[] array, final int length) {
return doResize(array, length);
}
/**
* Returns an array containing the same elements as the given {@code array} but
* specified {@code length}, truncating or padding with zeros if necessary.
*
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*/
public static char[] resize(final char[] array, final int length) {
return doResize(array, length);
}
/**
* Returns an array containing the same elements as the given {@code array} but
* specified {@code length}, truncating or padding with zeros if necessary.
*
* @param array Array to copy.
* @param length Length of the desired array.
* @return A new array of the requested length, or {@code array} if the original
* array already have the requested length.
*/
public static boolean[] resize(final boolean[] array, final int length) {
return doResize(array, length);
}
/**
* Removes elements from the middle of an array.
*
* @param <T> The type of array elements.
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
private static <T> T doRemove(final T array, final int index, final int length) {
if (length == 0) {
return array;
}
int arrayLength = Array.getLength(array);
@SuppressWarnings("unchecked")
final T newArray = (T) Array.newInstance(array.getClass().getComponentType(), arrayLength -= length);
System.arraycopy(array, 0, newArray, 0, index);
System.arraycopy(array, index+length, newArray, index, arrayLength-index);
return newArray;
}
/**
* Removes elements from the middle of an array.
*
* @param <E> The type of array elements.
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static <E> E[] remove(final E[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Removes elements from the middle of an array.
*
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static double[] remove(final double[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Removes elements from the middle of an array.
*
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static float[] remove(final float[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Removes elements from the middle of an array.
*
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static long[] remove(final long[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Removes elements from the middle of an array.
*
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static int[] remove(final int[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Removes elements from the middle of an array.
*
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static short[] remove(final short[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Removes elements from the middle of an array.
*
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static byte[] remove(final byte[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Removes elements from the middle of an array.
*
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static char[] remove(final char[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Removes elements from the middle of an array.
*
* @param array Array from which to remove elements.
* @param index Index of the first element to remove from the given {@code array}.
* @param length Number of elements to remove.
* @return Array with the same elements than the given {@code array} except for the
* removed elements, or {@code array} if {@code length} is 0.
*/
public static boolean[] remove(final boolean[] array, final int index, final int length) {
return doRemove(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to {@code null}.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
private static <T> T doInsert(final T array, final int index, final int length) {
if (length == 0) {
return array;
}
final int arrayLength = Array.getLength(array);
@SuppressWarnings("unchecked")
final T newArray = (T) Array.newInstance(array.getClass().getComponentType(), arrayLength + length);
System.arraycopy(array, 0, newArray, 0, index );
System.arraycopy(array, index, newArray, index+length, arrayLength-index);
return newArray;
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to {@code null}.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static <E> E[] insert(final E[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to zeros.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static double[] insert(final double[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to zeros.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static float[] insert(final float[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to zeros.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static long[] insert(final long[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to zeros.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static int[] insert(final int[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to zeros.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static short[] insert(final short[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to zeros.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static byte[] insert(final byte[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to zeros.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static char[] insert(final char[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts spaces into the middle of an array. These "spaces" will be made up of elements
* initialized to {@code false}.
*
* @param array Array in which to insert spaces.
* @param index Index where the first space should be inserted. All {@code array} elements
* having an index equal to or higher than {@code index} will be moved forward.
* @param length Number of spaces to insert.
* @return Array containing the {@code array} elements with the additional space
* inserted, or {@code array} if {@code length} is 0.
*/
public static boolean[] insert(final boolean[] array, final int index, final int length) {
return doInsert(array, index, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Table to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
// Returns type should be T, but it doesn't seem to work with Java 5.
// Revisit when we will be allowed to compile for Java 6 (it does work for the later).
private static <T> Object doInsert(final T src, final int src_pos,
final T dst, final int dst_pos, final int length)
{
if (length == 0) {
return dst;
}
final int dstLength = Array.getLength(dst);
@SuppressWarnings("unchecked")
final T newArray = (T) Array.newInstance(dst.getClass().getComponentType(), dstLength+length);
System.arraycopy(dst, 0, newArray, 0, dst_pos );
System.arraycopy(src, src_pos, newArray, dst_pos, length );
System.arraycopy(dst, dst_pos, newArray, dst_pos+length, dstLength-dst_pos);
return newArray;
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
@SuppressWarnings("unchecked")
public static <E> E[] insert(final E[] src, final int src_pos,
final E[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (E[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
public static double[] insert(final double[] src, final int src_pos,
final double[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (double[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
public static float[] insert(final float[] src, final int src_pos,
final float[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (float[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
public static long[] insert(final long[] src, final int src_pos,
final long[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (long[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
public static int[] insert(final int[] src, final int src_pos,
final int[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (int[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
public static short[] insert(final short[] src, final int src_pos,
final short[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (short[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to
* insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
public static byte[] insert(final byte[] src, final int src_pos,
final byte[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (byte[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
public static char[] insert(final char[] src, final int src_pos,
final char[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (char[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Inserts a table slice into another table. The {@code src} table
* will be entirely or partially inserted into the {@code dst} table.
*
* @param src Tablea to insert into {@code dst}.
* @param src_pos Index of the first data item of {@code src} to insert into {@code dst}.
* @param dst Table in which to insert {@code src} data.
* @param dst_pos {@code dst} index in which to insert {@code src} data. All elements of
* {@code dst} whose index is equal to or greater than {@code dst_pos} will
* be moved forward.
* @param length Number of {@code src} data items to insert.
* @return Table which contains the combination of {@code src} and {@code dst}. This
* method can directly return {@code dst}, but never {@code src}. It most
* often returns a newly created table.
*/
public static boolean[] insert(final boolean[] src, final int src_pos,
final boolean[] dst, final int dst_pos, final int length)
{
// Following cast is required for Java 5 (remove with Java 6).
return (boolean[]) doInsert(src, src_pos, dst, dst_pos, length);
}
/**
* Returns {@code true} if all elements in the specified array are in increasing order.
* This method is usefull in assertions.
*/
public static <T> boolean isSorted(final T[] array, final Comparator<T> comparator) {
for (int i=1; i<array.length; i++) {
if (comparator.compare(array[i], array[i-1]) < 0) {
return false;
}
}
return true;
}
/**
* Returns {@code true} if all elements in the specified array are in increasing order.
* This method is usefull in assertions.
*/
public static boolean isSorted(final char[] array) {
for (int i=1; i<array.length; i++) {
if (array[i] < array[i-1]) {
return false;
}
}
return true;
}
/**
* Returns {@code true} if all elements in the specified array are in increasing order.
* This method is usefull in assertions.
*/
public static boolean isSorted(final byte[] array) {
for (int i=1; i<array.length; i++) {
if (array[i] < array[i-1]) {
return false;
}
}
return true;
}
/**
* Returns {@code true} if all elements in the specified array are in increasing order.
* This method is usefull in assertions.
*/
public static boolean isSorted(final short[] array) {
for (int i=1; i<array.length; i++) {
if (array[i] < array[i-1]) {
return false;
}
}
return true;
}
/**
* Returns {@code true} if all elements in the specified array are in increasing order.
* This method is usefull in assertions.
*/
public static boolean isSorted(final int[] array) {
for (int i=1; i<array.length; i++) {
if (array[i] < array[i-1]) {
return false;
}
}
return true;
}
/**
* Returns {@code true} if all elements in the specified array are in increasing order.
* This method is usefull in assertions.
*/
public static boolean isSorted(final long[] array) {
for (int i=1; i<array.length; i++) {
if (array[i] < array[i-1]) {
return false;
}
}
return true;
}
/**
* Returns {@code true} if all elements in the specified array are in increasing order.
* Since {@code NaN} values are unordered, they may appears anywhere in the array; they
* will be ignored. This method is usefull in assertions.
*/
public static boolean isSorted(final float[] array) {
int previous = 0;
for (int i=1; i<array.length; i++) {
final float value = array[i];
if (value < array[previous]) {
return false;
}
if (!Float.isNaN(value)) {
previous = i;
}
}
return true;
}
/**
* Returns {@code true} if all elements in the specified array are in increasing order.
* Since {@code NaN} values are unordered, they may appears anywhere in the array; they
* will be ignored. This method is usefull in assertions.
*/
public static boolean isSorted(final double[] array) {
int previous = 0;
for (int i=1; i<array.length; i++) {
final double value = array[i];
if (value < array[previous]) {
return false;
}
if (!Double.isNaN(value)) {
previous = i;
}
}
return true;
}
/**
* Returns {@code true} if all elements in the specified array are in strictly increasing order.
* This method is usefull in assertions.
*/
public static boolean isStrictlySorted(final int[] array) {
for (int i=1; i<array.length; i++) {
if (array[i] <= array[i-1]) {
return false;
}
}
return true;
}
/**
* Returns {@code true} if all values in the specified array are equals to the specified
* value, which may be {@link Float#NaN}.
*/
public static boolean allEquals(final float[] array, final float value) {
if (Float.isNaN(value)) {
for (int i=0; i<array.length; i++) {
if (!Float.isNaN(array[i])) {
return false;
}
}
} else {
for (int i=0; i<array.length; i++) {
if (array[i] != value) {
return false;
}
}
}
return true;
}
/**
* Returns {@code true} if all values in the specified array are equals to the specified
* value, which may be {@link Double#NaN}.
*/
public static boolean allEquals(final double[] array, final double value) {
if (Double.isNaN(value)) {
for (int i=0; i<array.length; i++) {
if (!Double.isNaN(array[i])) {
return false;
}
}
} else {
for (int i=0; i<array.length; i++) {
if (array[i] != value) {
return false;
}
}
}
return true;
}
/**
* Returns {@code true} if the specified array contains at least one
* {@link Float#NaN NaN} value.
*/
public static boolean hasNaN(final float[] array) {
for (int i=0; i<array.length; i++) {
if (Float.isNaN(array[i])) {
return true;
}
}
return false;
}
/**
* Returns {@code true} if the specified array contains at least one
* {@link Double#NaN NaN} value.
*/
public static boolean hasNaN(final double[] array) {
for (int i=0; i<array.length; i++) {
if (Double.isNaN(array[i])) {
return true;
}
}
return false;
}
/**
* Returns {@code true} if the specified array contains the specified value, ignoring case.
* This method should be used only for very small arrays.
*
* @param array The array to search in. May be {@code null}.
* @param value The value to search.
* @return {@code true} if the array contains the value.
*/
public static boolean containsIgnoreCase(final String[] array, final String value) {
if (array != null) {
for (final String element : array) {
if (value.equalsIgnoreCase(element)) {
return true;
}
}
}
return false;
}
/**
* Returns {@code true} if the specified array contains the specified value. This method
* should be used only for very small arrays, or for search to be performed only once,
* because it performs a linear search. If more than one search need to be done on the
* same array, consider using {@link java.util.HashSet} instead.
*
* @param array The array to search in. May be {@code null} and may contains null elements.
* @param value The value to search. May be {@code null}.
* @return {@code true} if the array contains the value.
*/
public static boolean contains(final Object[] array, final Object value) {
if (array != null) {
for (final Object element : array) {
if (Utilities.equals(element, value)) {
return true;
}
}
}
return false;
}
/**
* Returns {@code true} if at least one element in the first array is {@linkplain Object#equals
* equals} to an element in the second array. The element doesn't need to be at the same index
* in both array.
* <p>
* This method should be used only for very small arrays since it may be very slow. If the
* arrays are large or if an array will be involved in more than one search, consider using
* {@link java.util.HashSet} instead.
*/
public static boolean intersects(final Object[] array1, final Object[] array2) {
for (final Object element : array1) {
if (contains(array2, element)) {
return true;
}
}
return false;
}
/**
* Returns a string representation of an array of numbers. Current implementation
* supports only primitive or subclasses of {@link Number}.
*
* @param array The array to format.
* @param locale The locale for formatting.
* @return The formatted array.
*
* @todo The separator should be local-dependent.
* @todo Should we implements this functionality in {@link org.geotools.io.LineFormat} instead?
*/
public static String toString(final Object array, final Locale locale) {
final StringBuffer buffer = new StringBuffer();
final NumberFormat format = NumberFormat.getNumberInstance(locale);
final FieldPosition dummy = new FieldPosition(0);
final int length = Array.getLength(array);
for (int i=0; i<length; i++) {
if (i != 0) {
buffer.append(", "); // TODO: the separator should be local-dependent.
}
format.format(Array.get(array, i), buffer, dummy);
}
return buffer.toString();
}
}