Java泛型问题

时间:2016-04-05 15:20:35

标签: java generics

我试图用仿制药做点什么,我似乎无法弄明白。所以我有这个界面。

public interface Transformation<A,B> {
    public B transform(A a);
}

我有一个实现它的课程。

public class AveragingTransformer implements Transformation<List<Long>,Double> {

    public Double transform(List<Long> a) {
        return a.get(0).doubleValue()/a.get(1);
    }

}

所以在我的主要方法中,我有这个......

public static void main(String[] args){
    ....
    Transformation<List<?>,Double> transformation = new AveraginTransformer();
    ....
}

但由于某种原因,这不起作用,任何人都可以帮助我理解为什么吗?

修改

所以问题是如果我想将数组传递给我的转换,我似乎无法让编译器接受它。

所以说我有......

public class foo<T>{

    T val;
    Transformation<? extends List<?>,T> transformation; //This gets initialized by constructor, where I will pass in the averaging transformer in this case.

    public void setVal(List<?> list){
        val = transformation.transform(list);
    }

}

如果我尝试这样做,就会给我这个错误

enter image description here

但是我想保持转换的左侧部分是通用的,因为不同的foos会以不同的方式使用可能不同的数据来计算它们的值。即一些foos可能会从字符串列表中计算出它们的val,但如果我为每个字符串提供正确的变换器,那么它应该可以工作。

2 个答案:

答案 0 :(得分:3)

您必须完全匹配泛型:

    Transformation<List<Long>,Double> transformation  = new AveragingTransformer();

即。将List<?>更改为List<Long>

如果您希望该工具应用于多种类型,请选择适当的已实现界面。例如这里Long实现了Number,所以我将回到List<Number>

public interface Transformation<A, B> {

    public B transform(A a);
}

public class AveragingTransformer implements Transformation<List<Number>, Double> {

    @Override
    public Double transform(List<Number> a) {
        return a.stream().mapToDouble(v -> v.doubleValue()).average().orElse(0);
    }

}

public void test() {
    Transformation<List<Number>, Double> transformation = new AveragingTransformer();
}

答案 1 :(得分:0)

啊,所以我终于明白了,因为OldCurmudgeon指出问题是通配符。问题是编译器不知道所有这些实际上最终都是相同的,这意味着我的Foo类实际上有另一个我没想到的Type参数,用于计算结束的值的类型结果

public class Foo<T,I>{

    T val;
    Transformation<List<I>,T> transformation;

    public void setVal(List<I> list>){
        val = transformation.transform(list);
    }
}

public static void main(String[] args){
    Foo<Double,Number> foo = nee Foo(new AveragingTransformer());
    List<Number> nums = new Arraylist<Number>();
    nums.add(2);
    nums.add(3);
    foo.setValue(nums);
}

感谢您指出我正确的方向!