I have searched for this, but unfortunately, I don\'t get the correct answer.
class Helper {
public static T[] toArray(List list) {
You can't instantiate a Generic type like you did here:
T[] array = (T[]) new Object[list.size()];
As, if T
is bounded to a type, you're typecasting the new Object
array to a bounded type T
. I would suggest using List.toArray(T[]) method instead.
String[] array = list.toArray(new String[0]);
I use this simply function. IntelliJ just hates that type cast T[] but it works just fine.
public static <T> T[] fromCollection(Class<T> c, Collection<T> collection) {
return collection.toArray((T[])java.lang.reflect.Array.newInstance(c, collection.size()));
}
And call looks like this:
Collection<Integer> col = new ArrayList(Arrays.asList(1,2,3,4));
fromCollection(Integer.class, col);
You can just call list.toArray(T[] array) and not have to worry about implementing it yourself, but as aioobe said, you can't create an array of a generic type due to type erasure. If you need that type back, you need to create a typed instance yourself and pass it in.
This is due to type erasure. The generics are removed in compilation, thus the Helper.toArray
will be compiled into returning an Object[]
.
For this particular case, I suggest you use List.toArray(T[]).
String[] array = list.toArray(new String[list.size()]);
Just copy interface and class inside your project. This :
public interface LayerDataTransformer<F, T> {
T transform(F from);
Collection<T> transform(Collection<F> from);
T[] toArray(Collection<F> from);
}
and this :
public abstract class BaseDataLayerTransformer<F, T> implements LayerDataTransformer<F, T> {
@Override
public List<T> transform(Collection<F> from) {
List<T> transformed = new ArrayList<>(from.size());
for (F fromObject : from) {
transformed.add(transform(fromObject));
}
return transformed;
}
@Override
public T[] toArray(Collection<F> from) {
Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
T[] transformedArray = (T[]) java.lang.reflect.Array.newInstance(clazz, from.size());
int index = 0;
for (F fromObject : from) {
transformedArray[index] = transform(fromObject);
index++;
}
return transformedArray;
}
}
Usage.
Declare a subclass of BaseDataLayerTransformer
public class FileToStringTransformer extends BaseDataLayerTransformer<File,String> {
@Override
public String transform(File file) {
return file.getAbsolutePath();
}
}
And use :
FileToStringTransformer transformer = new FileToStringTransformer();
List<File> files = getFilesStub();// returns List<File>
//profit!
String[] filePathArray = transformer.toArray(files);