我试图用仿制药做点什么,我似乎无法弄明白。所以我有这个界面。
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);
}
}
如果我尝试这样做,就会给我这个错误
但是我想保持转换的左侧部分是通用的,因为不同的foos会以不同的方式使用可能不同的数据来计算它们的值。即一些foos可能会从字符串列表中计算出它们的val,但如果我为每个字符串提供正确的变换器,那么它应该可以工作。
答案 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);
}
感谢您指出我正确的方向!