我目前正在攻读面向对象编程,我目前正在研究泛型一章。我有一个来自Java类的以下代码,我要求的是使最后一个方法 calculateSquares 泛型。我真的很困惑,我可以告诉你。
以下是课程:
public class OefeningWildcards {
public static void main(String[] args){
new OefeningWildcards().run();
}
public OefeningWildcards(){
}
public void run(){
Number[] numbers = {2, 3.1, 5, 12, 2.3};
List<Number> numbersList = new ArrayList<>();
for (Number n : numbers){
numbersList.add(n);
List<Number> dest = new ArrayList<>();
calculateSquares(dest, numbersList);
Double[] doubles = {3.2, 5.6, 4.4, 6.5, 12.2};
List<Double> doublesList = new ArrayList<>();
List<Number> dest2 = new ArrayList<>();
calculateSquares(dest2, doublesList);
List<Double> dest3 = new ArrayList<>();
calculateSquares(dest3, doublesList);
}
}
//This method needs to become generic
public void calculateSquares(List<Number> dest, List<Number> src){
dest.clear();
for (Number n : src) {
dest.add(n * n.intValue());
dest.add(n.doubleValue() * n.doubleValue());
}
}
我发现列表编号需要成为列表?扩展数字,如下所示:
public void calculateSquares(List<? extends Number> dest, List<? extends Number> src){
dest.clear();
for (Number n : src) {
dest.add(n * n.intValue());
dest.add(n.doubleValue() * n.doubleValue());
}
}
事情是,我不知道如何处理for循环:
for (Number n : src) {
dest.add(n * n.intValue());
dest.add(n.doubleValue() * n.doubleValue());
}
}
我的逻辑猜测是:
for (? extends Number n : src) {
dest.add(n * n.intValue());
dest.add(n.doubleValue() * n.doubleValue());
}
}
但这似乎是不正确的。我应该怎么做for循环?
答案 0 :(得分:2)
你实际要求的是不可能的。至少您无法将目的地列表更改为? extends Number
。因为那时你不知道列表是哪种类型。如果是List<Integer>
,则无法在其中添加Double
值。但是,你可以做的是使源通用。
要做的是将泛型类型添加到方法声明
public void <T extends Number> calculateSquares(List<Number> dest, List<T> src){
dest.clear();
for (T n : src) {
dest.add(n * n.intValue());
dest.add(n.doubleValue() * n.doubleValue());
}
}
实际上,一旦离开目的地,您也可以离开旧方法。它仍然有效:
public void calculateSquares(List<Number> dest, List<? extends Number> src){
dest.clear();
for (Number n : src) {
dest.add(n * n.intValue());
dest.add(n.doubleValue() * n.doubleValue());
}
}
因为您似乎想要向目标添加List<Double>
或List<Number>
。通过更改第一个List并使用超级运算符,可以再次实现这一点:
public void calculateSquares(List<? super Double> dest, List<? extends Number> src){
dest.clear();
for (Number n : src) {
dest.add((double)n * n.intValue());
dest.add(n.doubleValue() * n.doubleValue());
}
}
答案 1 :(得分:0)
首先,不需要传递dest List。改变参数值不是一个好习惯。我们可以将返回类型更改为List,自己创建一个新List并返回它。
其次,意味着您可以传递任何扩展数字的列表,但不能在其中添加任何内容。如果要添加,则需要将其更改为。有关详细说明,请参阅this SO答案。
第三,我们不需要添加两次方块。只需添加一次即可。请参阅以下示例:
public List<Number> calculateSquares(List<? extends Number> src){
List<Number> squares = new ArrayList<>();
for (Number n : src) {
squares.add(n.doubleValue() * n.doubleValue());
}
return squares;
}