Java Collection Type Parameter to array

KimchiMan :

I want to create a helper method which gets Collection type parameter to return a list. This is what I have now:

public class Helper {
    public static <T> T[] CollectionToArray(Collection<T> collection) {
        return collection.stream().toArray(Object[]::new); // Error
    }

    public static <T> T[] ListToArray(List<T> list) {
        return list.stream().toArray(Object[]::new); // Error
    }
}

public class IamSoNoob {
    public void PleaseHelpMe() {

        List<String> list = new ArrayList<>();
        Set<String> set = new HashSet<>();

        String[] arrayFromList = Helper.CollectionToArray(list); // Error
        String[] arrayFromSet = Helper.CollectionToArray(set); // Error

        String[] array = Helper.ListToArray(list); // Error
    }
}

My questions are:

  1. Is it possible to complete CollectionToArray(Collection<T>)?
    • If so, how?
    • Also, is it possible to pass List and Set as a parameter in the first place?
  2. Is it possible to complete ListToArray(List<T> list)?
    • If so, how?

But here are some restrictions due to my personal taste.

  1. I don't want to use @SuppressWarnings
  2. I really want to keep the part .stream().toArray(Object[]::new) (Java 8 part!)

And I have a feeling that I need to fix the part Object[]::new by using something like: <T extends Object> or <? extends T> but I can't really figure out.

Please help me out, and please provide an explanation as well, I am often confused by Generic and ?.

Ryotsu :

No, you absolutely cannot do it, if it were possible the library method Collection.toArray() would've given you the same type as your LHS but instead when you want the exact type as your LHS you have to use Collection.toArray(T[]) (even that comes with ArrayStoreExceptions i.e it is up to the programmer to provide the right type for the array), the reason being that in your toArray() you've specified Object[] to be your array and later you cannot cast it to any other type or else it will result in a ClassCastException.

The reason for all this hullabaloo is because of the way generics works i.e its a compile time thing and at runtime Java erases all type parameters to their upper bound types and hence losing type information which is required for creating arrays.

One safe way of doing it is by adding another paramter to you helper method as

public static <T> T[] CollectionToArray(Collection<T> collection, T[] arr) {

            return collection.stream().toArray(value ->Arrays.copyOf(arr,collection.size()));


        }

and using it as

String[] arrayFromList = Helper.CollectionToArray(list, new String[0]);

but then everybody's better off using Collection#toArray(T[]).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=132498&siteId=1