数组的Java集合类型参数

时间:2018-12-02 03:15:53

标签: java class generics java-8 abstract-class

我想创建一个获取Collection类型参数以返回列表的辅助方法。这就是我现在拥有的:

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
    }
}

我的问题是:

  1. 是否可以完成CollectionToArray(Collection<T>)
    • 如果是,怎么办?
    • 还可以首先传递ListSet作为参数吗?
  2. 是否可以完成ListToArray(List<T> list)
    • 如果是,怎么办?

但是由于我的个人品味,这里有些限制。

  1. 我不想使用@SuppressWarnings
  2. 我真的很想保留.stream().toArray(Object[]::new)部分(Java 8部分!)

我有一种感觉,我需要使用Object[]::new<T extends Object>之类的东西来修复<? extends T>零件,但我真的不知道。

请帮助我,并提供解释,Generic?经常使我感到困惑。

1 个答案:

答案 0 :(得分:2)

不,您绝对不能这样做,如果库方法Collection.toArray()可以为您提供与LHS相同的类型,但是当您想要与LHS相同的类型时,则必须使用{ {1}}(甚至随Collection.toArray(T[])一起提供,即由程序员决定是否为数组提供正确的类型),原因是在ArrayStoreExceptions中指定了{{1} }作为数组,以后就不能将其强制转换为其他任何类型,否则将导致toArray()

所有这些麻烦的原因是由于泛型的工作方式,即它是编译时的事情,并且在运行时Java将所有类型参数擦除为其上限类型,因此丢失了创建数组所需的类型信息。

一种安全的方法是在辅助方法中添加另一个参数,例如

Object[]

并将其用作

ClassCastException

但是每个人最好使用 public static <T> T[] CollectionToArray(Collection<T> collection, T[] arr) { return collection.stream().toArray(value ->Arrays.copyOf(arr,collection.size())); }