package org.cumulus4j.testutil;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Utility mathods for collections.
*/
public class CollectionUtil
{
/*
* This method casts a {@link Collection} by instantiating an instance of one of
* the following classes:
*
* - {@link DelegatingSet}
* - {@link DelegatingList}
* - {@link DelegatingCollection}
*
* Which one of the above classes is chosen, depends on the interface implemented by
* the in
parameter.
*/
/**
* This method casts any collection into another.
* Warning: This should be used with care! Only use it, when you're absolutely sure that
* the cast is correct! This method is not type-safe!
*
* There are many situations where
* you are absolutely sure that your cast is correct, but illegal due to the way generics are
* implemented in Java. In these cases you can use this method which is not expensive since it
* returns exactly the parameter passed to it.
*
*
* @param in The collection that needs to be casted.
*/
@SuppressWarnings("unchecked")
public static Collection castCollection(final Collection> in)
{
return (Collection) in;
// if (in instanceof Set)
// return new DelegatingSet((Set) in);
// else if (in instanceof List)
// return new DelegatingList((List)in);
// else
// return new DelegatingCollection(in);
}
@SuppressWarnings("unchecked")
public static Collection castCollection(final Object obj) {
return (Collection) obj;
}
@SuppressWarnings("unchecked")
public static List castList(final List> in)
{
// return new DelegatingList(in);
return (List) in;
}
@SuppressWarnings("unchecked")
public static Set castSet(final Set> in)
{
// return new DelegatingSet(in);
return (Set) in;
}
@SuppressWarnings("unchecked")
public static Map castMap(final Map, ?> in)
{
return (Map) in;
}
/**
* Given an Object obj, usually from a resulting Object obtained after executing a query (in which this resulting Object
* is known to be a Collection of instances of the type T), return this as a HashSet of the type T.
*/
public static HashSet createHashSetFromCollection(final Object obj) {
final Collection extends T> results = CollectionUtil.castCollection(obj);
return new HashSet( results );
}
/**
* This method calls {@link Util#array2ArrayList(Object[], boolean)} with
* canReturnNull = true.
*
* @param objects An array of objects - can be null.
* @return Returns an ArrayList (or null if objects == null).
*/
public static ArrayList array2ArrayList(final T[] objects)
{
return array2ArrayList(objects, true);
}
/**
* @param canReturnNull If false, the result will never be null,
* but an empty list if objects is null.
* @param objects An array of objects - can be null.
* @return Returns an ArrayList - never null.
* The ArrayList is empty if objects is null and
* canReturnNull is false. If canReturnNull == true
* and objects == null, the result will be null.
*/
public static ArrayList array2ArrayList(final T[] objects, final boolean canReturnNull)
{
if (canReturnNull && objects == null)
return null;
final ArrayList l = new ArrayList(objects == null ? 0 : objects.length);
if (objects != null) {
for (final T element : objects)
l.add(element);
}
return l;
}
/**
* This method calls {@link Util#array2HashSet(Object[], boolean)} with
* canReturnNull = true.
*
* @param objects An array of objects - can be null.
* @return Returns an ArrayList (or null, if objects == null).
*/
public static HashSet array2HashSet(final T[] objects)
{
return CollectionUtil.array2HashSet(objects, true);
}
/**
* @param canReturnNull If false, the result will never be null,
* but an empty list if objects is null.
* @param objects An array of objects - can be null.
* @return a HashSet or null.
* The result is empty if objects is null and
* canReturnNull is false. If canReturnNull == true
* and objects == null, the result will be null.
*/
public static HashSet array2HashSet(final T[] objects, final boolean canReturnNull)
{
if (canReturnNull && objects == null)
return null;
final HashSet s = new HashSet(objects == null ? 0 : objects.length);
if (objects != null) {
for (final T element : objects)
s.add(element);
}
return s;
}
/**
* This method calls {@link Util#collection2TypedArray(Collection, Class, boolean)} with
* canReturnNull = true.
*
* @param c Either null or a Collection with instances of the type specified by clazz (or descendants of it).
* @param clazz The type of the elements of the returned object-array (e.g. String.class for the returned type String[]).
* @return Returns a typed object array (or null, if c == null).
*/
public static T[] collection2TypedArray(final Collection c, final Class clazz)
{
return CollectionUtil.collection2TypedArray(c, clazz, true);
}
/**
* @param c Either null or a Collection with instances of the type specified by clazz (or descendants of it).
* @param clazz The type of the elements of the returned object-array (e.g. String.class for the returned type String[]).
* @param canReturnNull If false, the result will never be null,
* but an empty array if c == null.
*
* @return Returns a typed object array (or null, if c == null && canReturnNull).
* If canReturnNull is false and c == null, an empty array will be returned.
*/
@SuppressWarnings("unchecked")
public static T[] collection2TypedArray(final Collection c, final Class clazz, final boolean canReturnNull)
{
if (canReturnNull && c == null)
return null;
final Object array = Array.newInstance(clazz, c == null ? 0 : c.size());
if (c != null) {
int i = 0;
for (final Object element : c)
Array.set(array, i++, element);
}
return (T[])array;
}
/**
* Merges all given Arrays to a new one and returns it.
*
* If passed only one array, that one will be returned, not a new one.
* If no array is passed, null
will be returned.
*
*
* @param The type of Array entries.
* @param ts The arrays to merge.
* @return A new array containing the entries of the given ones.
*/
public static T[] mergeArrays(final T[] ... ts)
{
if (ts.length == 0)
return null;
if (ts.length == 1)
return ts[0];
final List tList = array2ArrayList(ts[0]);
for (int i = 1; i < ts.length; i++) {
addAllToCollection(ts[i], tList);
}
return tList.toArray(ts[ts.length -1]);
}
/**
* Moves the given element up in the given list.
*
* @param list The list
* @param element The element
*/
public static void moveListElementUp(final List list, final T element)
{
final int index = list.indexOf(element);
if (index <= 0 || index >= list.size())
return;
list.remove(index);
list.add(index-1, element);
}
/**
* Moves the given element down in the given list.
* @param list The list
* @param element The element
*/
public static void moveListElementDown(final List list, final T element)
{
final int index = list.indexOf(element);
if (index < 0 || index >= list.size()-1)
return;
list.remove(index);
list.add(index+1, element);
}
@SuppressWarnings("unchecked")
public static > List enum2List(final Enum e)
{
return array2ArrayList((T[])e.getClass().getEnumConstants());
}
/**
* Create a string representation for the given collection.
* @param c The collection to create a string representation for
* @return The string representation for the given collection
*/
public static String toString(final Collection> c)
{
return toString(c, ",", true, null, false, "null");
}
/**
* Create a string representation for the given collection.
* @param c The collection to create a string representation for
* @param fieldPrefix A string to put before an element
* @param fieldPrefixBeforeFirst Whether to put fieldPrefix before the first element
* @param fieldSuffix A string to put after an element
* @param fieldSuffixAfterLast Whether to put fieldSuffix after the last element
* @param nullString The string to use as value when value is null
* @return The string representation for the given collection
*/
public static String toString(final Collection> c, final String fieldPrefix, final boolean fieldPrefixBeforeFirst, final String fieldSuffix, final boolean fieldSuffixAfterLast, final String nullString)
{
final StringBuffer s = new StringBuffer();
boolean first = true;
for (final Object object : c) {
if(fieldPrefix != null) {
if(first) {
first = false;
if(fieldPrefixBeforeFirst)
s.append(fieldPrefix);
} else {
s.append(fieldPrefix);
}
}
final String valueString = (object==null?(nullString==null?"":nullString):object.toString());
s.append(valueString);
if(fieldSuffix != null)
s.append(fieldSuffix);
}
if(!first && fieldSuffix != null && !fieldSuffixAfterLast)
s.delete(s.length()-fieldSuffix.length(), s.length());
return s.toString();
}
/**
* Create a string representation for the given map.
* @param m The map to create a string representation for
* @return The string representation for the given map
*/
public static String toString(final Map, ?> m)
{
return toString(m, ",", true, null, false, "[", "]", "=", "null");
}
/**
* Create a string representation for the given map.
* @param m The map to create a string representation for
* @param fieldPrefix A string to put before an element
* @param fieldPrefixBeforeFirst Whether to put fieldPrefix before the first element
* @param fieldSuffix A string to put after an element
* @param fieldSuffixAfterLast Whether to put fieldSuffix after the last element
* @param keyPrefix A string to put before the key
* @param keySuffix A string to put after the key
* @param assignmentString A string to put between the key and the value
* @param nullString The string to use as value when value is null
* @return The string representation for the given map
*/
public static String toString(final Map, ?> m, final String fieldPrefix, final boolean fieldPrefixBeforeFirst, final String fieldSuffix, final boolean fieldSuffixAfterLast, final String keyPrefix, final String keySuffix, final String assignmentString, final String nullString)
{
final StringBuffer s = new StringBuffer();
boolean first = true;
for (final Object key : m.keySet()) {
if(fieldPrefix != null) {
if(first) {
first = false;
if(fieldPrefixBeforeFirst)
s.append(fieldPrefix);
} else {
s.append(fieldPrefix);
}
}
if(keyPrefix != null)
s.append(keyPrefix);
s.append(key);
if(keySuffix != null)
s.append(keySuffix);
if(assignmentString != null)
s.append(assignmentString);
final Object value = m.get(key);
final String valueString = (value==null?(nullString==null?"":nullString):value.toString());
s.append(valueString);
if(fieldSuffix != null)
s.append(fieldSuffix);
}
if(!first && !fieldSuffixAfterLast && fieldSuffix != null)
s.delete(s.length()-fieldSuffix.length(), s.length());
return s.toString();
}
/**
* Create a string representation for the given array.
* @param array The array to create a string representation for
* @return The string representation for the given array
*/
public static String toString(final T[] array)
{
return toString(array, ",", true, null, false, "[", "]", "=", "null");
}
/**
* Create a string representation for the given array.
* @param array The array to create a string representation for
* @param fieldPrefix A string to put before an element
* @param fieldPrefixBeforeFirst Whether to put fieldPrefix before the first element
* @param fieldSuffix A string to put after an element
* @param fieldSuffixAfterLast Whether to put fieldSuffix after the last element
* @param keyPrefix A string to put before the index
* @param keySuffix A string to put after the index
* @param assignmentString A string to put between the index and the value
* @param nullString The string to use as value when value is null
* @return The string representation for the given array
*/
public static String toString(final T[] array, final String fieldPrefix, final boolean fieldPrefixBeforeFirst, final String fieldSuffix, final boolean fieldSuffixAfterLast, final String keyPrefix, final String keySuffix, final String assignmentString, final String nullString)
{
final StringBuffer s = new StringBuffer();
for(int i=0; i 0 || fieldPrefixBeforeFirst))
s.append(fieldPrefix);
if(keyPrefix != null)
s.append(keyPrefix);
s.append(i);
if(keySuffix != null)
s.append(keySuffix);
if(assignmentString != null)
s.append(assignmentString);
final Object value = array[i];
final String valueString = (value==null?(nullString==null?"":nullString):value.toString());
s.append(valueString);
if(fieldSuffix != null && (i
* Note that nothing will be done if the given object to replace is not contained
* in the given collection.
*
* @param collection The collection to replace values in.
* @param replace The object to be replaced.
* @param replacement The object that should be inserted into the collection.
*/
@SuppressWarnings("unchecked")
public static void replaceAllInCollection(final Collection collection, final Object replace, final Object replacement) {
if (collection instanceof List) {
final List list = (List) collection;
int idx = list.indexOf(replace);
while (idx >= 0) {
list.set(idx, replacement);
idx = list.indexOf(replace);
}
}
else {
if (collection.contains(replace)) {
collection.remove(replace);
collection.add(replacement);
}
}
}
/**
* Creates an ArrayList with an initial capacity of item.length
* and adds the given items to it.
*
* @param The type of the items.
* @param item The items to be added.
* @return Returns a new typed ArrayList which contains the given items.
*/
public static ArrayList createArrayList(final T ... item)
{
final ArrayList list = new ArrayList(item.length);
for (final T t : item)
list.add(t);
return list;
}
/**
* Creates a HashSet with an initial capacity of item.length
* and adds the given items to it.
*
* @param The type of the items.
* @param item The items to be added.
* @return Returns a new typed HashSet which contains the given items.
*/
public static HashSet createHashSet(final T ... item)
{
final HashSet set = new HashSet(item.length);
for (final T t : item)
set.add(t);
return set;
}
/**
* Adds all entries of the given array to the given list.
*
* @param The type of the items.
* @param array The array whose items should be added.
* @param list The list where the items should be added.
*/
public static void addAllToCollection(final T[] array, final List list)
{
for (final T t : array)
list.add(t);
}
}