Java为什么不将ArrayList <double>对象用作Collection <number>对象?

时间:2019-03-09 20:32:24

标签: java collections casting

我想计算任何整数或双精度集合的算术平均值。

我定义了以下方法:

public static double arithmeticMean(Collection<Number> collection) {

    for(Number element : collection)

        if (element.getClass().isInstance(Integer.class)) {

            Collection<Integer> intCollection = new ArrayList<>();
            for(Number number : collection)
                intCollection.add(number.intValue());
            return arithmeticMeanOfIntegers(intCollection);

        } else if (element.getClass().isInstance(Double.class)) {

            Collection<Double> doubleCollection = new ArrayList<>();
            for(Number number : collection)
                doubleCollection.add(number.doubleValue());
            return arithmeticMeanOfDoubles(doubleCollection);

        } 
    throw new IllegalArgumentException("Method 'arithmeticMean' only operates on integer or double types");      
}

要测试该方法,我创建一个Double的ArrayList,如下所示:

private static ArrayList<Double> dataSet = getDataSet();

private static ArrayList<Double> getDataSet() {
    ArrayList<Double> dataSet = new ArrayList<>();
    for(int i = 1; i < 21; i++)
        dataSet.add(new Double(i));
    return dataSet;
}

但是当我像这样调用算术平均值方法时:

public static void main(String[] args) {
    System.out.println(arithmeticMean(dataSet));
    System.out.println(arithmeticMean((Collection<Number>) dataSet));
}

第一次调用会导致错误:

The method arithmeticMean(Collection<Number>) in the type SimpleStats is not applicable for the arguments (ArrayList<Double>)

第二次调用导致错误:

Cannot cast from ArrayList<Double> to Collection<Number>

阅读了有关Collections的Oracle Java Tutorials部分后,我不明白为什么我不能将ArrayList对象传递给需要Collection的方法。 ArrayList从Collection继承,而Double从Number继承。

有人可以解释吗?

2 个答案:

答案 0 :(得分:0)

我还没有测试过,但是我认为这可行。更改方法参数的类型:

-0.000

public static double arithmeticMean(Collection<Number> collection) {

编辑:由于此操作可行,请阅读What is PECS?的答案。它将帮助您了解何时以及如何使用通用通配符。

答案 1 :(得分:0)

来自java tutorials

  

通常,如果FooBar的子类型(子类或子接口),而G是某种通用类型声明,则不是 G<Foo>G<Bar>的子类型的情况。这可能是您最需要了解泛型的知识,因为它违背了我们一贯的直觉。

在这种情况下,您应该使用wildcards,例如:Collection<? extends Number>

详细了解Generics, Inheritance, and Subtypes