【问题标题】:Java Collection Type Parameter to arrayJava 集合类型参数到数组
【发布时间】:2018-12-02 03:15:53
【问题描述】:

我想创建一个辅助方法,它获取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&lt;T&gt;)?
    • 如果是,怎么做?
    • 另外,是否可以首先将List 和Set 作为参数传递?
  2. 是否可以完成ListToArray(List&lt;T&gt; list)?
    • 如果是,怎么做?

但由于我的个人喜好,这里有一些限制。

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

我有一种感觉,我需要使用类似 &lt;T extends Object&gt; 或 &lt;? extends T&gt; 的方式来修复 Object[]::new 部分,但我真的不知道。

请帮帮我,也请提供一个解释,我经常被Generic和?弄糊涂。

【问题讨论】:

  • 如果可以单独从泛型类型构造数组,Stream.toArray() 将不需要任何参数。
  • 您需要接受另一个参数。 T[] 或 IntFunction&lt;T&gt;。
  • @shmosel 未检查的分配(T[]) collection.toArray() 怎么样?
  • @nullpointer 那是在乞求 ClassCastException。
  • 只使用Collections.toArray(T[ ]) 有什么坏处?你为什么不直接做 String[] arrayFromList =list.toArray(new String[0]); ?当标准库提供经过测试的、可信赖的且完全符合您要求的方法时,编写您自己的方法的原因是什么?

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


【解决方案1】:

不,您绝对不能这样做,如果库方法 Collection.toArray() 可能会为您提供与 LHS 相同的类型,但是当您想要与 LHS 完全相同的类型时,您必须使用 Collection.toArray(T[]) (即使ArrayStoreExceptions 附带,即由程序员为数组提供正确的类型),原因是在您的toArray() 中您已指定Object[] 为您的数组,后来您无法转换将其转换为任何其他类型,否则将导致ClassCastException。

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

一种安全的方法是向您的辅助方法添加另一个参数

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

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


        }

并将其用作

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

但是每个人都最好使用 Collection#toArray(T[]).

【讨论】:

  • 我删除了我的旧答案,因为它是错误的 - 感谢您的回答:)
猜你喜欢
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多