在 Java 中返回泛型类型的数组

我有一个类映射器,它应该将实现 Function 接口的任何对象应用于类型 D 的数组,并返回类型为 R 的数组。


问题是 Java 不允许我使用“new R[]”,到目前为止,我一直在努力寻找一种从头开始创建 R 数组的方法。我目前正在尝试使用 Array.newInstance 方法,但找不到将 R 的类类型存储在 Class 变量中的方法。


public class Mapper {



/**

 * applies passed function to each object of type D in array

 * @param function

 * @param array

 * @return array of type r and length array.length

 */


public static <R, D> R[] map(Function<R, D> function, D[] array)  {


    ArrayList<R> list = new ArrayList<R>();


    //apply function to each variable

    //add rs into object array

    for( int i = 0; i < array.length; i++ ) {


        R r = function.apply( array[i] );

        list.add( r );


    }




    Class<R> clazz = list.get(0).getClass();


    return (R[])Array.newInstance(clazz, list.size()); 


}


}

我可以在运行时为泛型类型 R 正确获取类值,或者以其他方式将 ArrayList 中的对象作为 R[] 返回?


三国纷争
浏览 267回答 2
2回答

喵喔喔

最简洁的方法是简单地将Class对象传递给函数。此外,您似乎可以Function颠倒类型参数的顺序——第一个类型参数应该是输入类型,第二个应该是结果类型。这样的事情应该让你更接近你想要的:public static <R, D> R[] map(Function<D, R> function, D[] array, Class<R> clazz)&nbsp; {&nbsp; &nbsp; R[] result = (R[]) Array.newInstance(clazz, array.length);&nbsp; &nbsp; // apply function to each variable and add return value to the result array&nbsp; &nbsp; for( int i = 0; i < array.length; i++ ) {&nbsp; &nbsp; &nbsp; &nbsp; result[i] = function.apply(array[i]);&nbsp; &nbsp; }&nbsp; &nbsp; return result;}(我还建议将类型参数的顺序颠倒到您的方法中,以与内置反射类(如Function.)保持一致。)

Smart猫小萌

您面临的问题与 Java 泛型类型擦除有关。由于所有泛型类型都在运行时被擦除,Java 必须进行权衡以保证类型安全。泛型数组的问题在于 Java 无法保证类型安全,您可以在此处找到一个很好的示例。简而言之,不允许创建通用数组。要保留大部分原始代码,您可以使用Object[]:public static <D, R> Object[] map(Function<D, R> function, D[] array) {&nbsp; &nbsp; List<R> list = new ArrayList<>();&nbsp; &nbsp; for (int i = 0; i < array.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; R r = function.apply(array[i]);&nbsp; &nbsp; &nbsp; &nbsp; list.add(r);&nbsp; &nbsp; }&nbsp; &nbsp; return list.toArray(new Object[0]); // no generic array creation allowed!}但是,这就是为什么大多数人坚持使用列表的原因,因为在涉及泛型时使用它们更容易:public static <D, R> List<R> map(Function<D, R> function, List<D> array) {&nbsp; &nbsp; List<R> list = new ArrayList<>();&nbsp; &nbsp; for (D d : array) {&nbsp; &nbsp; &nbsp; &nbsp; list.add(function.apply(d));&nbsp; &nbsp; }&nbsp; &nbsp; return list;}这样做的好处是,当具体类型已知时,您仍然可以在之后将其转换为数组:List<String> strings = List.of("Test1", "Test2");String[] array = map(String::toLowerCase, strings).toArray(new String[0]);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java