首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java中返回泛型类型的数组

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

Stack Overflow用户
提问于 2018-10-07 08:45:33
回答 2查看 915关注 0票数 0

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

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

代码语言:javascript
复制
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的类值,或者以R[]的形式返回ArrayList中的对象?

EN

回答 2

Stack Overflow用户

发布于 2018-10-07 09:22:50

您面临的问题与Java泛型类型擦除有关。由于所有泛型类型都会在运行时被擦除,因此Java必须做出权衡,以保证类型安全。

泛型数组的问题是Java不能保证类型安全,你可以找到关于这个here的一个很好的例子。简而言之,不允许创建泛型数组。

要保留大部分原始代码,可以使用Object[]

代码语言:javascript
复制
public static <D, R> Object[] map(Function<D, R> function, D[] array) {
    List<R> list = new ArrayList<>();
    for (int i = 0; i < array.length; i++) {
        R r = function.apply(array[i]);
        list.add(r);
    }
    return list.toArray(new Object[0]); // no generic array creation allowed!
}

但是,这就是为什么大多数人坚持使用列表,因为当涉及到泛型时,使用它们会更容易:

代码语言:javascript
复制
public static <D, R> List<R> map(Function<D, R> function, List<D> array) {
    List<R> list = new ArrayList<>();
    for (D d : array) {
        list.add(function.apply(d));
    }
    return list;
}

这样做的好处是,当知道具体类型时,您仍然可以将其转换为数组:

代码语言:javascript
复制
List<String> strings = List.of("Test1", "Test2");
String[] array = map(String::toLowerCase, strings).toArray(new String[0]);
票数 0
EN

Stack Overflow用户

发布于 2018-10-07 10:02:28

要做到这一点,最简单的方法是简单地将Class对象传递给函数。而且,您似乎颠倒了Function类型参数的顺序--第一个类型参数应该是输入类型,第二个类型参数应该是结果类型。像这样的东西应该会让你更接近你想要的:

代码语言:javascript
复制
public static <R, D> R[] map(Function<D, R> function, D[] array, Class<R> clazz)  {

    R[] result = (R[]) Array.newInstance(clazz, array.length);

    // apply function to each variable and add return value to the result array
    for( int i = 0; i < array.length; i++ ) {
        result[i] = function.apply(array[i]);
    }

    return result;
}

(我还建议颠倒方法的类型参数顺序,以便与Function等内置反射类保持一致。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52684545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档