|
|
@@ -20,6 +20,8 @@ import net.ranides.assira.generic.Function;
|
|
|
import net.ranides.assira.generic.ValueUtils;
|
|
|
import net.ranides.assira.math.HashHelper;
|
|
|
import net.ranides.assira.reflection.ClassInspector;
|
|
|
+import net.ranides.assira.reflection.UnsafeArrayAccess;
|
|
|
+import net.ranides.assira.trace.LoggerUtils;
|
|
|
|
|
|
/**
|
|
|
* Operacje na tablicach.
|
|
|
@@ -69,7 +71,7 @@ public final class ArrayUtils {
|
|
|
* @param clazz szukana klasa
|
|
|
* @return
|
|
|
*/
|
|
|
- public static <T> T first(Object[] values, Class<T> clazz) {
|
|
|
+ public static <K, T extends K> T first(K[] values, Class<T> clazz) {
|
|
|
if(null == values) { return null; }
|
|
|
for (int i=0, n=values.length; i<n; i++) {
|
|
|
if( clazz.isInstance(values[i]) ) { return clazz.cast(values[i]); }
|
|
|
@@ -85,8 +87,10 @@ public final class ArrayUtils {
|
|
|
* @param values tablica, w której obiekt klasy jest szukany
|
|
|
* @return
|
|
|
*/
|
|
|
- public static <T> T first(T[] values) { // @test
|
|
|
- if(null == values || 0==values.length) { return null; }
|
|
|
+ public static <T> T first(T[] values) {
|
|
|
+ if(null == values || 0==values.length) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
return values[0];
|
|
|
}
|
|
|
|
|
|
@@ -99,8 +103,10 @@ public final class ArrayUtils {
|
|
|
* @param clazz szukana klasa
|
|
|
* @return
|
|
|
*/
|
|
|
- public static <T> T last(Object[] values, Class<T> clazz) { // @test
|
|
|
- if(null == values) { return null; }
|
|
|
+ public static <T> T last(Object[] values, Class<T> clazz) {
|
|
|
+ if(null == values) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
for (int i=values.length-1; i >= 0; i--) {
|
|
|
if( clazz.isInstance(values[i]) ) { return clazz.cast(values[i]); }
|
|
|
}
|
|
|
@@ -115,8 +121,10 @@ public final class ArrayUtils {
|
|
|
* @param values tablica, w której obiekt klasy jest szukany
|
|
|
* @return
|
|
|
*/
|
|
|
- public static <T> T last(T[] values) { // @test
|
|
|
- if(null == values || 0==values.length) { return null; }
|
|
|
+ public static <T> T last(T[] values) {
|
|
|
+ if(null == values || 0==values.length) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
return values[values.length - 1];
|
|
|
}
|
|
|
|
|
|
@@ -128,15 +136,15 @@ public final class ArrayUtils {
|
|
|
* @param values
|
|
|
* @return
|
|
|
*/
|
|
|
- public static <T> int size(T[] values) { // @test
|
|
|
+ public static <T> int size(T[] values) {
|
|
|
return null == values ? 0 : values.length;
|
|
|
}
|
|
|
|
|
|
- public static int size(Object values) { // @test
|
|
|
+ public static int size(Object values) {
|
|
|
if(null == values) {
|
|
|
return 0;
|
|
|
}
|
|
|
- if(values.getClass().isArray()) {
|
|
|
+ if(!values.getClass().isArray()) {
|
|
|
throw new IllegalArgumentException("type is not an array: " + values.getClass());
|
|
|
}
|
|
|
return Array.getLength(values);
|
|
|
@@ -150,7 +158,7 @@ public final class ArrayUtils {
|
|
|
* @param values
|
|
|
* @return
|
|
|
*/
|
|
|
- public static <T> boolean isEmpty(T[] values) { // @test
|
|
|
+ public static <T> boolean isEmpty(T[] values) {
|
|
|
return 0 == size(values);
|
|
|
}
|
|
|
|
|
|
@@ -162,59 +170,33 @@ public final class ArrayUtils {
|
|
|
* @param values
|
|
|
* @return
|
|
|
*/
|
|
|
- public static <T> boolean isEmpty(Object values) { // @test
|
|
|
+ public static <T> boolean isEmpty(Object values) {
|
|
|
return 0 == size(values);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Porównuje rozmiary tablic.
|
|
|
- *
|
|
|
- * <table style="margin: 10px 0 0 0; background: #c0F0c0; border: solid 1px #006000;" cellpadding="0"><tr><td>{@code null} safe method</td></tr></table>
|
|
|
- * @param <T1>
|
|
|
- * @param <T2>
|
|
|
- * @param a
|
|
|
- * @param b
|
|
|
- * @return
|
|
|
- * <table>
|
|
|
- * <tr><td>ujemne</td><td> - jeśli a < b</td></tr>
|
|
|
- * <tr><td>dodatnie</td><td> - jeśli a > b </td></tr>
|
|
|
- * <tr><td>dodatnie</td><td> - jeśli a == b </td></tr>
|
|
|
- * </table>
|
|
|
- */
|
|
|
- public static <T1,T2> int compareSize(T1[] a, T2[] b) { // @test
|
|
|
- return size(a) - size(b);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Sprawdza, czy tablice mają ten sam rozmiar.
|
|
|
- * Tablice, które są równe {@code null} traktowane są jako puste (rozmiar 0).
|
|
|
- *
|
|
|
- * <table style="margin: 10px 0 0 0; background: #c0F0c0; border: solid 1px #006000;" cellpadding="0"><tr><td>{@code null} safe method</td></tr></table>
|
|
|
- * @param <T1>
|
|
|
- * @param <T2>
|
|
|
- * @param a
|
|
|
- * @param b
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static <T1,T2> boolean equalSize(T1[] a, T2[] b) { // @test
|
|
|
- return size(a) == size(b);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* Przycina tablicę, jeśli tablica ma długość większą od podanej granicy.
|
|
|
* @param <T>
|
|
|
- * @param list
|
|
|
+ * @param array
|
|
|
* @param size maksymalna długość tablicy
|
|
|
* @return {@code list} albo nowa tablica, jeśli konieczne było obcięcie
|
|
|
*/
|
|
|
+ public static <T> T[] clip(T[] array, int size) {
|
|
|
+ if( array.length <= size ) {
|
|
|
+ return array;
|
|
|
+ }
|
|
|
+ T result[] = make(array.getClass(), size);
|
|
|
+ System.arraycopy(array, 0, result, 0, size);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
@SuppressWarnings("unchecked")
|
|
|
- public static <T> T[] clip(T[] list, int size) { // @test
|
|
|
- if( list.length <= size ) {
|
|
|
- return list;
|
|
|
+ public static <ArrayT> ArrayT clip(ArrayT array, int size) {
|
|
|
+ if( size(array) <= size ) {
|
|
|
+ return array;
|
|
|
}
|
|
|
- T result[] = (T[])Array.newInstance(list.getClass().getComponentType(), size);
|
|
|
- System.arraycopy(list, 0, result, 0, size);
|
|
|
+ ArrayT result= make(array.getClass(), size);
|
|
|
+ System.arraycopy(array, 0, result, 0, size);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
@@ -308,75 +290,19 @@ public final class ArrayUtils {
|
|
|
* odpowiednich rzutowań i unbox'owań, jeśli są konieczne. Zwrócona tablica jest
|
|
|
* niezależna od listy.
|
|
|
* @param <T>
|
|
|
- * @param arrayClazz
|
|
|
+ * @param array
|
|
|
* @param source
|
|
|
* @return
|
|
|
* @throws ClassCastException jeśli konwersja elementów jest niemożliwa do przeprowadzenia
|
|
|
*/
|
|
|
@SuppressWarnings({"PMD", "unchecked"})
|
|
|
- public static <T> T toArray(Class<T> arrayClazz, List<?> source) throws ClassCastException {
|
|
|
- int count = source.size();
|
|
|
- if ( boolean[].class.equals(arrayClazz) ) {
|
|
|
- boolean[] result = new boolean[count];
|
|
|
- for(int i=0; i<count; i++) { result[i] = (Boolean)source.get(i); }
|
|
|
- return (T)result;
|
|
|
- }
|
|
|
- if ( char[].class.equals(arrayClazz) ) {
|
|
|
- char[] result = new char[count];
|
|
|
- for(int i=0; i<count; i++) { result[i] = (Character)source.get(i); }
|
|
|
- return (T)result;
|
|
|
- }
|
|
|
- if ( byte[].class.equals(arrayClazz) ) {
|
|
|
- byte[] result = new byte[count];
|
|
|
- for(int i=0; i<count; i++) { result[i] = (Byte)source.get(i); }
|
|
|
- return (T)result;
|
|
|
- }
|
|
|
- if ( short[].class.equals(arrayClazz) ) {
|
|
|
- short[] result = new short[count];
|
|
|
- for(int i=0; i<count; i++) { result[i] = (Short)source.get(i); }
|
|
|
- return (T)result;
|
|
|
- }
|
|
|
- if ( int[].class.equals(arrayClazz) ) {
|
|
|
- int[] result = new int[count];
|
|
|
- for(int i=0; i<count; i++) { result[i] = (Integer)source.get(i); }
|
|
|
- return (T)result;
|
|
|
- }
|
|
|
- if ( long[].class.equals(arrayClazz) ) {
|
|
|
- long[] result = new long[count];
|
|
|
- for(int i=0; i<count; i++) { result[i] = (Long)source.get(i); }
|
|
|
- return (T)result;
|
|
|
- }
|
|
|
- if ( float[].class.equals(arrayClazz) ) {
|
|
|
- float[] result = new float[count];
|
|
|
- for(int i=0; i<count; i++) { result[i] = (Float)source.get(i); }
|
|
|
- return (T)result;
|
|
|
- }
|
|
|
- if ( double[].class.equals(arrayClazz) ) {
|
|
|
- double[] result = new double[count];
|
|
|
- for(int i=0; i<count; i++) { result[i] = (Double)source.get(i); }
|
|
|
- return (T)result;
|
|
|
- }
|
|
|
- try {
|
|
|
- Object[] result = (Object[])Array.newInstance(arrayClazz.getComponentType(), count);
|
|
|
- for(int i=0; i<count; i++) { result[i] = source.get(i); }
|
|
|
- return (T)result;
|
|
|
- } catch(ArrayStoreException cause) {
|
|
|
- throw new ClassCastException("cannot cast " + cause.getMessage() + " to " + arrayClazz.getComponentType());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Tworzy nową tablicę o podanym rozmiarze, która może przechowywać obiekty
|
|
|
- * podanego typu. Metoda nie nadaje się do tworzenia tablic typu prostego.
|
|
|
- * Do utworzenia takich tablic użyj jednej z funkcji {@link #nCopies}.
|
|
|
- * @param <T>
|
|
|
- * @param componentClass
|
|
|
- * @param count
|
|
|
- * @return
|
|
|
- */
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- public static <T extends Object> T[] make(Class<T> componentClass, int count) {
|
|
|
- return (T[])Array.newInstance(componentClass, count);
|
|
|
+ public static <Auto> Auto toArray(Class<?> type, List<?> source) throws ClassCastException {
|
|
|
+ UnsafeArrayAccess access = UnsafeArrayAccess.forType(type);
|
|
|
+ int size = source.size();
|
|
|
+ Object target = access.create(size);
|
|
|
+ int index = 0;
|
|
|
+ for(Object item : source) { access.put(target, index++, item); }
|
|
|
+ return (Auto)target;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -390,7 +316,9 @@ public final class ArrayUtils {
|
|
|
*/
|
|
|
public static <K extends Comparable<K>, V> void sort(V[] values, K[] keys) {
|
|
|
final Pair[] table = new Pair[keys.length];
|
|
|
- for(int i=0; i<table.length; i++) { table[i] = new Pair<K>(keys[i], values[i]); }
|
|
|
+ for(int i=0; i<table.length; i++) {
|
|
|
+ table[i] = new Pair<K>(keys[i], values[i]);
|
|
|
+ }
|
|
|
java.util.Arrays.sort(table);
|
|
|
|
|
|
|
|
|
@@ -423,7 +351,7 @@ public final class ArrayUtils {
|
|
|
|
|
|
/* ************************************************************************** */
|
|
|
|
|
|
- private static class Pair<K extends Comparable<K>> implements Comparable<Pair<K>> {
|
|
|
+ static class Pair<K extends Comparable<K>> implements Comparable<Pair<K>> {
|
|
|
public final K key;
|
|
|
public final Object value;
|
|
|
|
|
|
@@ -483,186 +411,82 @@ public final class ArrayUtils {
|
|
|
|
|
|
/* ************************************************************************** */
|
|
|
|
|
|
- /**
|
|
|
- * Zobacz: {@link #nCopies(int, java.lang.Object) nCopies}
|
|
|
- * @param size
|
|
|
- * @param value
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static char[] nCopies(int size, char value) { // @test
|
|
|
- char[] content = new char[size];
|
|
|
- if(value!=0) { for(int i=0; i<size; i++) { content[i] = value; } }
|
|
|
- return content;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #nCopies(int, java.lang.Object) nCopies}
|
|
|
- * @param size
|
|
|
- * @param value
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static short[] nCopies(int size, short value) { // @test
|
|
|
- short[] content = new short[size];
|
|
|
- if(value!=0) { for(int i=0; i<size; i++) { content[i] = value; } }
|
|
|
- return content;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #nCopies(int, java.lang.Object) nCopies}
|
|
|
- * @param size
|
|
|
- * @param value
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static int[] nCopies(int size, int value) { // @test
|
|
|
- int[] content = new int[size];
|
|
|
- if(value!=0) { for(int i=0; i<size; i++) { content[i] = value; } }
|
|
|
- return content;
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <Auto> Auto make(Class<?> type, int size) {
|
|
|
+ return (Auto)UnsafeArrayAccess.forType(type).create(size);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Zobacz: {@link #nCopies(int, java.lang.Object) nCopies}
|
|
|
- * @param size
|
|
|
- * @param value
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static long[] nCopies(int size, long value) { // @test
|
|
|
- long[] content = new long[size];
|
|
|
- if(value!=0) { for(int i=0; i<size; i++) { content[i] = value; } }
|
|
|
- return content;
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <Auto> Auto make(Class<?> type, int size, Object value) {
|
|
|
+ UnsafeArrayAccess access = UnsafeArrayAccess.forType(type);
|
|
|
+ Object content = access.create(size);
|
|
|
+ if(size != 0 && value!=null) {
|
|
|
+ for(int i=0; i<size; i++) { access.put(content, i, value); }
|
|
|
+ }
|
|
|
+ return (Auto)content;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Zobacz: {@link #nCopies(int, java.lang.Object) nCopies}
|
|
|
- * @param size
|
|
|
- * @param value
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static float[] nCopies(int size, float value) { // @test
|
|
|
- float[] content = new float[size];
|
|
|
- if(value!=0) { for(int i=0; i<size; i++) { content[i] = value; } }
|
|
|
- return content;
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <Auto> Auto make(int size, Object value) {
|
|
|
+ assert value != null : "value must be specified";
|
|
|
+
|
|
|
+ Class<?> type = ClassInspector.unbox(value.getClass());
|
|
|
+ UnsafeArrayAccess access = UnsafeArrayAccess.forType(type);
|
|
|
+ Object content = access.create(size);
|
|
|
+ for(int i=0; i<size; i++) {
|
|
|
+ access.put(content, i, value);
|
|
|
+ }
|
|
|
+ return (Auto)content;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Zobacz: {@link #nCopies(int, java.lang.Object) nCopies}
|
|
|
+ * Tworzy nową tablicę o podanym rozmiarze, która może przechowywać obiekty
|
|
|
+ * podanego typu. Metoda nie nadaje się do tworzenia tablic typu prostego.
|
|
|
+ * Do utworzenia takich tablic użyj jednej z funkcji {@link #nCopies}.
|
|
|
+ * @param <T>
|
|
|
+ * @param component
|
|
|
* @param size
|
|
|
- * @param value
|
|
|
* @return
|
|
|
*/
|
|
|
- public static double[] nCopies(int size, double value) { // @test
|
|
|
- double[] content = new double[size];
|
|
|
- if(value!=0.0) { for(int i=0; i<size; i++) { content[i] = value; } }
|
|
|
- return content;
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <T extends Object> T[] makeT(Class<T> component, int size) {
|
|
|
+ return (T[])Array.newInstance(component, size);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Tworzy tablicę o podanym rozmiarze, w całości zainicjalizowaną podaną wartością.
|
|
|
- * @param <T>
|
|
|
- * @param size rozmiar tablicy
|
|
|
- * @param value wartość, która zostanie przypisana do każdej komórki w tablicy
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static <T> T[] nCopies(int size, T value) {
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- T[] content = (T[])make(value.getClass(), size);
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <T extends Object> T[] makeT(Class<T> component, int size, T value) {
|
|
|
+ T[] content = makeT(component, size);
|
|
|
for(int i=0; i<size; i++) { content[i] = value; }
|
|
|
return content;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Zobacz: {@link #shift(Object[]) shift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static byte shift(byte[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- byte value = values[0];
|
|
|
- for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #shift(Object[]) shift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static char shift(char[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- char value = values[0];
|
|
|
- for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #shift(Object[]) shift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static short shift(short[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- short value = values[0];
|
|
|
- for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #shift(Object[]) shift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static int shift(int[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- int value = values[0];
|
|
|
- for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #shift(Object[]) shift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static long shift(long[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- long value = values[0];
|
|
|
- for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #shift(Object[]) shift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static float shift(float[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- float value = values[0];
|
|
|
- for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; }
|
|
|
- return value;
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <T> T[] makeT(int size, T value) {
|
|
|
+ return makeT((Class<T>)value.getClass(), size, value);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Zobacz: {@link #shift(Object[]) shift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static double shift(double[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- double value = values[0];
|
|
|
- for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* Zobacz: {@link #shift(Object[]) shift}
|
|
|
* @param values
|
|
|
* @return
|
|
|
*/
|
|
|
- public static boolean shift(boolean[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- boolean value = values[0];
|
|
|
- for(int i=1,n=values.length; i<n; i++) { values[i-1] = values[i]; }
|
|
|
- return value;
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public static <Auto> Auto shift(Object values) {
|
|
|
+ if(values == null) { // @test
|
|
|
+ throw new EmptyCollectionException();
|
|
|
+ }
|
|
|
+ UnsafeArrayAccess access = UnsafeArrayAccess.forObject(values);
|
|
|
+ int n = access.length(values);
|
|
|
+ if(n == 0) { // @test
|
|
|
+ throw new EmptyCollectionException();
|
|
|
+ }
|
|
|
+ Object value = access.get(values, 0);
|
|
|
+ for(int i=1; i<n; i++) {
|
|
|
+ access.put(values, i-1, access.get(values, i));
|
|
|
+ }
|
|
|
+ return (Auto)value;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -684,95 +508,20 @@ public final class ArrayUtils {
|
|
|
* @param values
|
|
|
* @return
|
|
|
*/
|
|
|
- public static byte unshift(byte[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- byte value = values[values.length-1];
|
|
|
- for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #unshift(Object[]) unshift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static short unshift(short[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- short value = values[values.length-1];
|
|
|
- for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #unshift(Object[]) unshift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static int unshift(int[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- int value = values[values.length-1];
|
|
|
- for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #unshift(Object[]) unshift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static long unshift(long[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- long value = values[values.length-1];
|
|
|
- for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #unshift(Object[]) unshift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static float unshift(float[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- float value = values[values.length-1];
|
|
|
- for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #unshift(Object[]) unshift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static double unshift(double[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- double value = values[values.length-1];
|
|
|
- for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #unshift(Object[]) unshift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static char unshift(char[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- char value = values[values.length-1];
|
|
|
- for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; }
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #unshift(Object[]) unshift}
|
|
|
- * @param values
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static boolean unshift(boolean[] values) {
|
|
|
- if(values == null || values.length==0) { throw new EmptyCollectionException(); }
|
|
|
- boolean value = values[values.length-1];
|
|
|
- for(int i=values.length-1; i>0; i--) { values[i] = values[i-1]; }
|
|
|
- return value;
|
|
|
+ public static <Auto> Auto unshift(Object values) {
|
|
|
+ if(values == null) { // @test
|
|
|
+ throw new EmptyCollectionException();
|
|
|
+ }
|
|
|
+ UnsafeArrayAccess access = UnsafeArrayAccess.forObject(values);
|
|
|
+ int n = access.length(values);
|
|
|
+ if(n == 0) { // @test
|
|
|
+ throw new EmptyCollectionException();
|
|
|
+ }
|
|
|
+ Object value = access.get(values, n-1);
|
|
|
+ for(int i=n-1; i>0; i--) {
|
|
|
+ access.put(values, i, access.get(values, i-1));
|
|
|
+ }
|
|
|
+ return (Auto)value;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -795,102 +544,14 @@ public final class ArrayUtils {
|
|
|
* @param second
|
|
|
* @return
|
|
|
*/
|
|
|
- public static byte[] concat(byte[] first, byte[] second) {
|
|
|
- byte[] result = new byte[ first.length + second.length ];
|
|
|
- System.arraycopy(first, 0, result, 0, first.length);
|
|
|
- System.arraycopy(second, 0, result, first.length, second.length);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #concat(Object[], Object[]) concat}
|
|
|
- * @param first
|
|
|
- * @param second
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static short[] concat(short[] first, short[] second) {
|
|
|
- short[] result = new short[ first.length + second.length ];
|
|
|
- System.arraycopy(first, 0, result, 0, first.length);
|
|
|
- System.arraycopy(second, 0, result, first.length, second.length);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #concat(Object[], Object[]) concat}
|
|
|
- * @param first
|
|
|
- * @param second
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static int[] concat(int[] first, int[] second) {
|
|
|
- int[] result = new int[ first.length + second.length ];
|
|
|
- System.arraycopy(first, 0, result, 0, first.length);
|
|
|
- System.arraycopy(second, 0, result, first.length, second.length);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #concat(Object[], Object[]) concat}
|
|
|
- * @param first
|
|
|
- * @param second
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static long[] concat(long[] first, long[] second) {
|
|
|
- long[] result = new long[ first.length + second.length ];
|
|
|
- System.arraycopy(first, 0, result, 0, first.length);
|
|
|
- System.arraycopy(second, 0, result, first.length, second.length);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #concat(Object[], Object[]) concat}
|
|
|
- * @param first
|
|
|
- * @param second
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static float[] concat(float[] first, float[] second) {
|
|
|
- float[] result = new float[ first.length + second.length ];
|
|
|
- System.arraycopy(first, 0, result, 0, first.length);
|
|
|
- System.arraycopy(second, 0, result, first.length, second.length);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #concat(Object[], Object[]) concat}
|
|
|
- * @param first
|
|
|
- * @param second
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static double[] concat(double[] first, double[] second) {
|
|
|
- double[] result = new double[ first.length + second.length ];
|
|
|
- System.arraycopy(first, 0, result, 0, first.length);
|
|
|
- System.arraycopy(second, 0, result, first.length, second.length);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #concat(Object[], Object[]) concat}
|
|
|
- * @param first
|
|
|
- * @param second
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static char[] concat(char[] first, char[] second) {
|
|
|
- char[] result = new char[ first.length + second.length ];
|
|
|
- System.arraycopy(first, 0, result, 0, first.length);
|
|
|
- System.arraycopy(second, 0, result, first.length, second.length);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Zobacz: {@link #concat(Object[], Object[]) concat}
|
|
|
- * @param first
|
|
|
- * @param second
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static boolean[] concat(boolean[] first, boolean[] second) {
|
|
|
- boolean[] result = new boolean[ first.length + second.length ];
|
|
|
- System.arraycopy(first, 0, result, 0, first.length);
|
|
|
- System.arraycopy(second, 0, result, first.length, second.length);
|
|
|
- return result;
|
|
|
+ @SuppressWarnings("SuspiciousSystemArraycopy")
|
|
|
+ public static <ArrayT> ArrayT concat(ArrayT first, ArrayT second) {
|
|
|
+ int length1 = size(first);
|
|
|
+ int length2 = size(second);
|
|
|
+ Object result = make(first.getClass(), length1 + length2);
|
|
|
+ System.arraycopy(first, 0, result, 0, length1);
|
|
|
+ System.arraycopy(second, 0, result, length1, length2);
|
|
|
+ return (ArrayT)result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -972,7 +633,7 @@ public final class ArrayUtils {
|
|
|
@SuppressWarnings("unchecked")
|
|
|
public static <T> T[] arraycopy(T[] target, Object[] source) { // @test
|
|
|
Class<T> component = (Class<T>)target.getClass().getComponentType();
|
|
|
- T[] result = target.length >= source.length ? target : make(component, source.length) ;
|
|
|
+ T[] result = target.length >= source.length ? target : makeT(component, source.length);
|
|
|
|
|
|
for(int i=0, n=source.length; i<n; i++) {
|
|
|
result[i] = component.cast(source[i]);
|
|
|
@@ -1000,11 +661,11 @@ public final class ArrayUtils {
|
|
|
* @param source
|
|
|
* @return
|
|
|
*/
|
|
|
- public static Object arraycopy(Object source) { // @test
|
|
|
- int size = Array.getLength(source);
|
|
|
- Object target = Array.newInstance(source.getClass().getComponentType());
|
|
|
+ public static <ArrayT> ArrayT arraycopy(ArrayT source) { // @test
|
|
|
+ int size = size(source);
|
|
|
+ Object target = make(source.getClass(), size);
|
|
|
System.arraycopy(source, 0, target, 0, size);
|
|
|
- return target;
|
|
|
+ return (ArrayT)target;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1037,55 +698,6 @@ public final class ArrayUtils {
|
|
|
return indexOf(array, value) >= 0;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Porównuje zawartość tablic, i zwraca {@code true}, jeśli są równe.
|
|
|
- * @param array1
|
|
|
- * @param array2
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static boolean isEqual(byte[] array1, byte[] array2) { // @test
|
|
|
- if (array1==array2) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- if (array1==null || array2==null) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- int n = array1.length;
|
|
|
- if (array2.length != n) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- for (int i=0; i<n; i++) {
|
|
|
- if (array1[i] != array2[i]) { return false; }
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Porównuje pierwsze {@code size} elementów w tablicach, i zwraca {@code true},
|
|
|
- * jeśli są równe.
|
|
|
- * @param size
|
|
|
- * @param array1
|
|
|
- * @param array2
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static boolean isEqual(int size, byte[] array1, byte[] array2) { // @test
|
|
|
- if (array1==array2) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- if (array1==null || array2==null) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- if(array1.length != array2.length && (array1.length < size || array2.length < size) ) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- for (int i=0, n=Math.min(array1.length, size); i<n; i++) {
|
|
|
- if (array1[i] != array2[i]) { return false; }
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
public static <S> Object[] apply(S[] values, Function<?,S> function) { // @test
|
|
|
final int n = values.length;
|
|
|
Object[] target = new Object[values.length];
|