1

我想从一个方法返回 2 种不同类型的类(List<double[]>或),如下面的伪代码所示。List<Double[]如何做到这一点?

编辑的代码和注释:Eclipse 甚至不允许编译,因为它要求更改返回或数据类型。我了解 YserieScaledCasted 必须手动进行投射。

protected List<E[]> getYserieRescaledList(Class<E> c) {

    if (Double[].class == c)
        return this.YserieScaled;
    else if (double[].class == c)
        return this.YserieScaledCasted;

}

EDIT2:我发现我的问题的正确方法是重载这里描述的方法。

4

3 回答 3

2

你意识到你正在返回一个数组列表,对吧?:-)

简短的回答:

  • 即使您正在传入Class<E>,您也不能在泛型类型上使用 instanceof 运算符,因此您不能执行上面概述的 if 语句

  • 以下是非法的,并且不会在两个 instanceof 运算符中的每一个上编译:

class trash {
    protected <T> List<T[]> getYserieRescaledList(Class<T> cl) {
       List<T[]> result = null;
       if (cl instanceof Class<Double>) {
               result = ...;
       } else if (cl instanceof Class<double>) {
               result = ...;
       }
       return result;
    }
}
  • 这样做的原因是泛型是仅编译时的构造。所有实例化的泛型类都转换为非泛型类,插入类型并执行类型转换等。询问泛型类是否在运行时用特定类型实例化是没有意义的——泛型类已被替换为非泛型类。泛型类

  • 相反,删除 if 语句并简单地使用实例化类型来声明变量和数组,然后使用您的算法填充它们并返回结果:

class treasure {
    protected <T> List<T[]> getYserieRescaledList(Class<T> cl) {
       List<T[]> result = null;
       // apply general algorithm here to populate the array
       // will work identically whether instantiated with Double or double
       return result;
    }
}

更长的答案:

泛型类应该代表可以应用于各种特定实例化类型的通用处理的“模板逻辑”。

很好的例子是 java Collections、持久性查询框架(例如 JPA Criteria API)、用于不同类型投资的财务计算器,甚至是具有标准服务“容器”基础架构逻辑的 SOA 服务模板。

在您的情况下,使用伪方法重载(即名称略有不同的两个方法)可能更简单:

protected List<Double[]> getYserieRescaledList() {
    return this.Y;
}

protected List<double[]> getYserieRescaledList2() {
    return this.YCasted;
}

或者甚至更好,只是坚持 double[] 作为唯一的情况。当您将值提取到其他变量/方法参数中时,编译器将根据需要透明地进行从 double 到 Double 的自动装箱转换。

于 2012-11-02T02:43:18.010 回答
1

这里发生了一些有趣的事情。所以你List<double[]>是一个包含原始s的List<Array>对象。Arraydouble

我敢说泛型在这里不是正确的解决方案。

我认为您最好的选择是使用 Google Lists 库。

像这样的东西:

protected List<Double[]> getYserieRescaledList() {
   return this.YseriesScaled;
}

然后,无论您拨打什么电话,您getYseriesRescaledList()都可以执行以下操作来获得List<double[]>

Lists.transform(getYseriesRescaledList(), toPrimitiveDouble());

这将使用下面的函数(来自 Google Guava)在一行代码中构造一个 List 对象:

private Function<Double[], double[]> toPrimitiveDouble(){
    return new Function<Double[], double[]>() {
        @Override
        public double[] apply( Double[] doubles) {
            double[] doubleArray = new double[doubles.length];

            int i = 0;
            for (Double doubleObject : doubles){
                doubleArray[i] = doubleObject.doubleValue();
                ++i;
            }

            return doubleArray;
        }
    };
}
于 2012-11-02T00:55:35.957 回答
1

只需使用Double[].classdouble[].class。请注意,您不能将 aDouble[]转换为 a double[],反之亦然,您必须手动复制它。因此,通过扩展,您不能List<Double[]>转换为List<double[]>任何一个。编辑:尽管乍一看,这似乎是您要纠正的限制。

于 2012-11-02T00:13:32.797 回答