package com.spun.util; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.lambda.functions.Function1; /** * A static class of convenience methods for arrays and collections. **/ public class ArrayUtils { /************************************************************************/ public static <T> java.util.Collection<T> addArray(java.util.Collection<T> v, T array[]) { if ((array == null) || (v == null)) { return v; } for (int i = 0; i < array.length; i++) { v.add(array[i]); } return v; } public static <T> String toString(T[] values, Function1<T, String> formatter) { return toString(Arrays.asList(values), formatter); } public static <T> String toString(Iterable<T> values, Function1<T, String> formatter) { StringBuffer b = new StringBuffer(); for (T t : values) { b.append(formatter.call(t) + "\n"); } return b.toString(); } /***********************************************************************/ public static Vector toReverseVector(Vector<Object> vector) { Vector<Object> reverse = new Vector<Object>(vector.size()); for (int i = vector.size() - 1; i >= 0; i--) { reverse.add(vector.elementAt(i)); } return reverse; } /***********************************************************************/ public static <T> T[] toReverseArray(T[] array) { for (int i = 0; i < array.length / 2; i++) { T o1 = array[i]; int end = array.length - i - 1; T o2 = array[end]; array[i] = o2; array[end] = o1; } return array; } /***********************************************************************/ public static <T> T[] addToArray(T[] array, T object) { Object[] newArray = null; if (array == null) { newArray = (Object[]) Array.newInstance(object.getClass(), 1); newArray[0] = object; } else { newArray = (Object[]) Array.newInstance(array.getClass().getComponentType(), array.length + 1); System.arraycopy(array, 0, newArray, 0, array.length); newArray[array.length] = object; } return (T[]) newArray; } /***********************************************************************/ public static <T> T[] getSubsection(T[] array, int startInclusive, int endExclusive) { int length = endExclusive - startInclusive; length = length > array.length ? array.length : length; T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), length); System.arraycopy(array, startInclusive, newArray, 0, length); return newArray; } /***********************************************************************/ public static boolean isEmpty(Object[] array) { return ((array == null) || (array.length == 0)); } /************************************************************************/ public static boolean isEmpty(Collection collection) { return ((collection == null) || (collection.size() == 0)); } /***********************************************************************/ public static <T> T getSingleton(T[] parts) { if (parts == null) { return null; } switch (parts.length) { case 0 : return null; case 1 : return parts[0]; default : throw new Error("Called with more than one object in the array " + Arrays.asList(parts)); } } /***********************************************************************/ public static <H, T extends H> T getFirst(T[] array, Comparator<H> compartor) { return get(array, compartor, true); } /***********************************************************************/ public static <H, T extends H> T getFirst(Collection<T> array, Comparator<H> sorter) { return get((T[]) array.toArray(), sorter, true); } /***********************************************************************/ public static <T> T getLast(T[] array, Comparator<T> sorter) { return get(array, sorter, false); } /***********************************************************************/ public static <T> T getLast(Collection<T> array, Comparator<T> sorter) { return get((T[]) array.toArray(), sorter, false); } /***********************************************************************/ private static <H, T extends H> T get(T[] array, Comparator<H> sorter, boolean wantFirst) { if (isEmpty(array)) { return null; } T last = array[0]; for (int i = 1; i < array.length; i++) { int compare = sorter.compare(last, array[i]); if ((wantFirst && compare > 0) || (!wantFirst && compare < 0)) { last = array[i]; } } return last; } /***********************************************************************/ public static List combineResults(Object[] array, String invokeMethod) { if (ArrayUtils.isEmpty(array)) { return Collections.EMPTY_LIST; } try { return combineResults(array, ObjectUtils.getGreatestCommonDenominator(array, invokeMethod)); } catch (Exception e) { throw ObjectUtils.throwAsError(e); } } /***********************************************************************/ @SuppressWarnings("rawtypes") public static List combineResults(Object[] array, Method method) { if (isEmpty(array)) { return new ArrayList(0); } try { ArrayList<Object> list = new ArrayList<Object>(); for (int i = 0; i < array.length; i++) { addArray(list, (Object[]) method.invoke(array[i], (Object[]) null)); } return list; } catch (Throwable e) { throw ObjectUtils.throwAsError(e); } } /***********************************************************************/ public static Object[] combine(Object[] a, Object[] b) { if (isEmpty(a) && isEmpty(b)) { if (a != null) { return (Object[]) Array.newInstance(a.getClass().getComponentType(), 0); } else if (b != null) { return (Object[]) Array.newInstance(b.getClass().getComponentType(), 0); } else { return new Object[0]; } } else if (isEmpty(a)) { return b; } else if (isEmpty(b)) { return a; } else { Object[] newArray = null; newArray = (Object[]) Array.newInstance(a.getClass().getComponentType(), a.length + b.length); System.arraycopy(a, 0, newArray, 0, a.length); System.arraycopy(b, 0, newArray, a.length, b.length); return newArray; } } /***********************************************************************/ public static <T> boolean contains(T[] values, T value) { for (int i = 0; i < values.length; i++) { if (value.equals(values[i])) { return true; } } return false; } /***********************************************************************/ public static boolean contains(int[] values, int value) { for (int i = 0; i < values.length; i++) { if (value == values[i]) { return true; } } return false; } /************************************************************************/ public static <T> T getLast(List<T> list) { return list.get(list.size() - 1); } /************************************************************************/ public static <K, T> T getDefault(HashMap<K, T> map, K key, T defaultValue) { T value = map.get(key); if (value == null) { map.put(key, defaultValue); value = defaultValue; } return value; } /************************************************************************/ public static <K, V> int countValues(HashMap<K, V> out, V matching) { return count(matching, out.values()); } /************************************************************************/ public static <V> int count(V matching, Collection<V> values) { int count = 0; for (V value : values) { if (matching.equals(value)) { count++; } } return count; } public static <T> List<T> combine(List<T> list1, List<T> list2) { List<T> all = new ArrayList<T>(); all.addAll(list1); all.addAll(list2); return all; } public static <T> Iterable<T> asIterable(Iterator<T> iterator) { return new IterableWrapper(iterator); } public static class IterableWrapper<T> implements Iterable<T> { private final Iterator<T> iterator; public IterableWrapper(Iterator<T> iterator) { this.iterator = iterator; } @Override public Iterator<T> iterator() { return iterator; } } }