I use to store lists/arrays of repeating objects as maps where key is the object itself and value is its multiplicity.
Say ['d', 'a', 'd', 'd', 'y']
--> {d=3, a=1, y=1}
(the order is preserved, FWIW)
I do this both for saving bytes and because manipulating this counting map makes my life easier
Sometimes I do need to revert to list/array form,
say {d=3, a=1, y=1}
--> ['d', 'd', 'd', 'a', 'y']
Clearly the original order can't be recreated, that information is lost, but that's unrelevant as I consider equivalent two lists/arrays if they have the same size and share exactly the same elements (including the relative multiplicity)
To get from Map to List I've written the following method :
<T> ArrayList<T> counted2Lst(final LinkedHashMap<T, Integer> map){
final ArrayList<T> grp=new ArrayList<T>(map.size()); // larger most of the times
for (final Entry<T, Integer> entry : map.entrySet()) {
final T obj=entry.getKey();
for(int i=entry.getValue(); i>0; i--){
grp.add(obj);
}
}
return grp;
}
Which does what it is expected to do : build an ArrayList out of a Map
I run into problems when I decided to do the same, but getting a T[] (NOT an Object[]) instead of an ArrayList
Here's my first attempt :
<T> T[] counted2Arry(final Map<T, Integer> map){
final ArrayList<T> tmpLst=counted2Lst(map); // method defined above
@SuppressWarnings("unchecked")
T[] arryT=(T[]) java.lang.reflect.Array.newInstance(tmpLst.get(0).getClass(), tmpLst.size());
return tmpLst.toArray(arryT);
}
As far as I know, due to type erasure, there's no way at runTime to get the parameterized type of a Collection/Map, so to actually create an array of T I had first to get the Class of the first object stored in tmpLst (granted to be of type T) and then making an array of T via java.lang.reflect.Array.newInstance()
Problem is that if the input map is empty (which is perfectly reasonable and legal case), then there's no object from which detecting the actual Class for T.
In other words, how can I say in Java ?
if(map.size()==0) { // or (tmpLst.size()==0)
// return a zero-sized T[0] (as opposed to a zero-sized Object[])
}