com.mockrunner.util.common.ArrayUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mockrunner-core Show documentation
Show all versions of mockrunner-core Show documentation
Core classes common to all Mockrunner modules
package com.mockrunner.util.common;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Util class for arrays
*/
public class ArrayUtil
{
/**
* Returns a List
containing the bytes from the
* specified array as Byte
objects.
* @param data the byte data
* @return the List
with the Byte
objects
*/
public static List getListFromByteArray(byte[] data)
{
ArrayList list = new ArrayList(data.length);
for(int ii = 0; ii < data.length; ii++)
{
list.add(data[ii]);
}
return list;
}
/**
* Returns a byte array containing the bytes from the List
.
* The List
must contain Byte
objects.
* null
entries in the List
are
* allowed, the resulting byte will be 0.
* @param data the List
* @return the resulting byte array
*/
public static byte[] getByteArrayFromList(List data)
{
return getByteArrayFromList(data, 0);
}
/**
* Returns a byte array containing the bytes from the List
.
* The List
must contain Byte
objects.
* null
entries in the List
are
* allowed, the resulting byte will be 0.
* @param data the List
* @param index the index at which to start
* @return the resulting byte array
*/
public static byte[] getByteArrayFromList(List data, int index)
{
return getByteArrayFromList(data, index, data.size() - index);
}
/**
* Returns a byte array containing the bytes from the List
.
* The List
must contain Byte
objects.
* null
entries in the List
are
* allowed, the resulting byte will be 0.
* @param data the List
* @param index the index at which to start
* @param len the number of bytes
* @return the resulting byte array
*/
public static byte[] getByteArrayFromList(List data, int index, int len)
{
if(data.size() == 0) return new byte[0];
if(index >= data.size())
{
throw new IndexOutOfBoundsException("Position " + index + " invalid in List of size " + data.size());
}
byte[] byteData = new byte[len];
for(int ii = index; ii < data.size() && ii < index + len; ii++)
{
Byte nextValue = data.get(ii);
if(null != nextValue)
{
byteData[ii - index] = nextValue;
}
}
return byteData;
}
/**
* Copies the bytes from the specified array to the specified
* List
as Byte
objects starting
* at the specified index. Grows the list if necessary.
* index must be a valid index in the list.
* @param data the byte data
* @param list the List
* @param index the index at which to start copying
*/
public static void addBytesToList(byte[] data, List list, int index)
{
addBytesToList(data, 0, data.length, list, index);
}
/**
* Copies the bytes from the specified array to the specified
* List
as Byte
objects starting
* at the specified index. Grows the list if necessary.
* index must be a valid index in the list.
* @param data the byte data
* @param offset the offset into the byte array at which to start
* @param len the number of bytes to copy
* @param list the List
* @param index the index at which to start copying
*/
public static void addBytesToList(byte[] data, int offset, int len, List list, int index)
{
int bytesToIncrease = index + len - list.size();
if(bytesToIncrease > 0)
{
for(int ii = 0; ii < bytesToIncrease; ii++)
{
list.add(null);
}
}
for(int ii = index; ii < index + len; ii++)
{
list.set(ii, data[offset + ii - index]);
}
}
/**
* Returns a truncated copy of sourceArray. len
* entries are copied.
* @param sourceArray the source array
* @param len the truncate length
* @return the truncated array
* @throws IllegalArgumentException if the specified object
* is not an array (either of reference or primitive
* component type)
*/
public static Object truncateArray(Object sourceArray, int len)
{
return truncateArray(sourceArray, 0, len);
}
/**
* Returns a truncated copy of sourceArray. len
* entries are copied starting at the specified index.
* @param sourceArray the source array
* @param index the start index
* @param len the truncate length
* @return the truncated array
* @throws IllegalArgumentException if the specified object
* is not an array (either of reference or primitive
* component type)
*/
public static Object truncateArray(Object sourceArray, int index, int len)
{
if(!sourceArray.getClass().isArray())
{
throw new IllegalArgumentException("sourceArray must be an array");
}
Object targetArray = Array.newInstance(sourceArray.getClass().getComponentType(), len);
System.arraycopy(sourceArray, index, targetArray, 0, len);
return targetArray;
}
/**
* Returns a copy of the specified array. If array
* is not an array, the object itself will be returned.
* Otherwise a copy of the array will be returned. The components
* themselves are not cloned.
* @param array the array
* @return the copy of the array
*/
public static Object copyArray(Object array)
{
if(!array.getClass().isArray()) return array;
Class componentType = array.getClass().getComponentType();
int length = Array.getLength(array);
Object copy = Array.newInstance(componentType, Array.getLength(array));
for(int ii = 0; ii < length; ii++)
{
Array.set(copy, ii, Array.get(array, ii));
}
return copy;
}
/**
* Returns an object array by wrapping primitive types. If the
* specified array is of primitive component type, an Object[]
* with the corresponding wrapper component type is returned.
* If the specified array is already an object array, the instance is
* returned unchanged.
* @param sourceArray the array
* @return the corresponding object array
* @throws IllegalArgumentException if the specified object
* is not an array (either of reference or primitive
* component type)
*/
public static Object[] convertToObjectArray(Object sourceArray)
{
if(!sourceArray.getClass().isArray())
{
throw new IllegalArgumentException("sourceArray must be an array");
}
Class componentType = sourceArray.getClass().getComponentType();
if(!componentType.isPrimitive())
{
return (Object[])sourceArray;
}
if(componentType.equals(Boolean.TYPE))
{
componentType = Boolean.class;
}
else if(componentType.equals(Byte.TYPE))
{
componentType = Byte.class;
}
else if(componentType.equals(Character.TYPE))
{
componentType = Character.class;
}
else if(componentType.equals(Short.TYPE))
{
componentType = Short.class;
}
else if(componentType.equals(Integer.TYPE))
{
componentType = Integer.class;
}
else if(componentType.equals(Long.TYPE))
{
componentType = Long.class;
}
else if(componentType.equals(Float.TYPE))
{
componentType = Float.class;
}
else if(componentType.equals(Double.TYPE))
{
componentType = Double.class;
}
int length = Array.getLength(sourceArray);
Object[] targetArray = (Object[])Array.newInstance(componentType, length);
for(int ii = 0; ii < length; ii++)
{
targetArray[ii] = Array.get(sourceArray, ii);
}
return targetArray;
}
/**
* Returns a primitive array by unwrapping the corresponding types. If the
* specified array is not an array of primitive wrapper types (e.g. Integer[]
),
* an IllegalArgumentException
will be thrown.
* If an array element is null
, an IllegalArgumentException
* will be thrown.
* @param sourceArray the array
* @return the corresponding primitive array
* @throws IllegalArgumentException if the specified array
* is not an array of primitive wrapper types or if an
* array element is null
*/
public static Object convertToPrimitiveArray(Object[] sourceArray)
{
Class componentType = sourceArray.getClass().getComponentType();
if(componentType.equals(Boolean.class))
{
componentType = Boolean.TYPE;
}
else if(componentType.equals(Byte.class))
{
componentType = Byte.TYPE;
}
else if(componentType.equals(Character.class))
{
componentType = Character.TYPE;
}
else if(componentType.equals(Short.class))
{
componentType = Short.TYPE;
}
else if(componentType.equals(Integer.class))
{
componentType = Integer.TYPE;
}
else if(componentType.equals(Long.class))
{
componentType = Long.TYPE;
}
else if(componentType.equals(Float.class))
{
componentType = Float.TYPE;
}
else if(componentType.equals(Double.class))
{
componentType = Double.TYPE;
}
else
{
throw new IllegalArgumentException("sourceArray is of type " + componentType + " which is not allowed");
}
int length = Array.getLength(sourceArray);
Object targetArray = Array.newInstance(componentType, length);
for(int ii = 0; ii < length; ii++)
{
Array.set(targetArray, ii, Array.get(sourceArray, ii));
}
return targetArray;
}
/**
* Creates an array with a single object as component.
* If the specified object is an array, it will be returned
* unchanged. Otherwise an array with the specified object
* as the single element will be returned.
* @param object the object
* @return the corresponding array
*/
public static Object convertToArray(Object object)
{
if(object.getClass().isArray()) return object;
Object array = Array.newInstance(object.getClass(), 1);
Array.set(array, 0, object);
return array;
}
/**
* Compares the two specified arrays. If both passed objects are
* null
, true
is returned. If both passed
* objects are not arrays, they are compared using equals
.
* Otherwise all array elements are compared using equals
.
* This method does not handle multidimensional arrays, i.e. if an
* array contains another array, comparison is based on identity.
* @param array1 the first array
* @param array2 the second array
* @return true
if the arrays are equal, false
* otherwise
*/
public static boolean areArraysEqual(Object array1, Object array2)
{
if(null == array1 && null == array2) return true;
if(null == array1 || null == array2) return false;
if(!array1.getClass().isArray() && !array2.getClass().isArray()) return array1.equals(array2);
if(!array1.getClass().isArray() || !array2.getClass().isArray()) return false;
int length1 = Array.getLength(array1);
int length2 = Array.getLength(array2);
if(length1 != length2) return false;
for(int ii = 0; ii < length1; ii++)
{
Object value1 = Array.get(array1, ii);
Object value2 = Array.get(array2, ii);
if(null != value1 && !value1.equals(value2)) return false;
if(null == value1 && null != value2) return false;
}
return true;
}
/**
* Returns a suitable hash code for the specified array. If the passed
* object is null
, 0
is returned.
* It is allowed to pass an object that is not an array, in this case,
* the hash code of the object will be returned. Otherwise the hash code
* will be based on the array elements. null
elements are
* allowed.
* This method does not handle multidimensional arrays, i.e. if an
* array contains another array, the hash code is based on identity.
* @param array the array
* @return a suitable hash code
*/
public static int computeHashCode(Object array)
{
if(null == array) return 0;
if(!array.getClass().isArray()) return array.hashCode();
int length = Array.getLength(array);
int hashCode = 17;
for(int ii = 0; ii < length; ii++)
{
Object value = Array.get(array, ii);
if(null != value) hashCode = (31 * hashCode) + value.hashCode();
}
return hashCode;
}
/**
* Returns the index of the first occurence of the
* array bytes in the array source.
* @param source the array in which to search
* @param bytes the array to search
* @return the index of the first occurence or
* -1, if source does not contain bytes
*/
public static int indexOf(byte[] source, byte[] bytes)
{
return indexOf(source, bytes, 0);
}
/**
* Returns the index of the first occurence of the
* array bytes in the array source.
* @param source the array in which to search
* @param bytes the array to search
* @param index the index where to begin the search
* @return the index of the first occurence or
* -1, if source does not contain bytes
*/
public static int indexOf(byte[] source, byte[] bytes, int index)
{
if(index + bytes.length > source.length) return -1;
for(int ii = index; ii <= source.length - bytes.length; ii++)
{
int yy = 0;
while(yy < bytes.length && bytes[yy] == source[ii + yy]) yy++;
if(yy == bytes.length) return ii;
}
return -1;
}
/**
* Ensures that each entry in the specified string array
* is unique by adding a number to duplicate entries.
* I.e. if the string "entry"
occurs three
* times, the three entries will be renamed to "entry1"
,
* "entry2"
and "entry3"
.
* @param values the array of strings
*/
public static void ensureUnique(String[] values)
{
Map nameMap = collectOccurences(values);
renameDuplicates(values, nameMap);
}
private static void renameDuplicates(String[] names, Map nameMap)
{
Iterator iterator = nameMap.keySet().iterator();
while(iterator.hasNext())
{
String nextName = (String)iterator.next();
Integer nextValue = (Integer)nameMap.get(nextName);
if(nextValue.intValue() > 1)
{
int number = 1;
for(int ii = 0; ii < names.length; ii++)
{
if(names[ii].equals(nextName))
{
names[ii] = nextName + number;
number++;
}
}
}
}
}
private static Map collectOccurences(String[] names)
{
Map nameMap = new HashMap();
for(int ii = 0; ii < names.length; ii++)
{
Integer currentValue = (Integer)nameMap.get(names[ii]);
if(null == currentValue)
{
nameMap.put(names[ii], new Integer(1));
}
else
{
nameMap.put(names[ii], new Integer(currentValue.intValue() + 1));
}
}
return nameMap;
}
}