List<Integer> 无法转换为 ArrayList<Integer>

7

我的代码开头有:

List<List<Integer>> result = new ArrayList();

然后,(这里是反转子列表):

List<Integer> sub = new ArrayList();
re = reverse(result.get(j)); // error occurs here

有这样一个方法:
public ArrayList<Integer> reverse(ArrayList<Integer> list) {
    List<Integer> newList = new ArrayList<>();

    for(int i=list.size()-1; i>=0; i--) {
        newList.add(list.get(i));}
        return newList;
    }
}

错误信息为:

无法将List转换为ArrayList

为什么会出现这种情况?

1
re 是如何声明的?请记住,List 不是 ArrayList,但反之亦然。 - Makoto
1
列表是接口,ArrayList 是实现 List 接口的类之一。所以,任何 ArrayList 都是 List(即 ArrayList 可以隐式赋值为 List),但反过来则不行。要么将返回类型更改为 List<Integer>,要么将 newList 变量类型更改为 ArrayList<Integer>。顺便说一下,将 "return" 移出循环体。 - AterLux
不要使用原始类型的 ArrayList。请使用 new ArrayList<>(); 而不是 new ArrayList(); - Jesper
3个回答

14

就像这样,你有一个名为reFruit(我使用这个名称是因为它是你正在使用的变量的名称)。

Fruit re;

你有一个名为reverse的方法,其输入类型为Apple

public Apple reverse(Apple a) {
    // ...
}

我们有一个变量re,我们将其声明为Fruit,这意味着我们说它总是会是某种Fruit,可能是Apple,但也可能是Orange - 甚至是Banana

当您尝试将Fruit提供给接受Apple的方法时,编译器会停止您,因为它无法确定它是否100%是一个Apple。例如...

Fruit re = new Orange();
reverse(re);

哎呀!换句话说,我们正在把一个方形钉子塞进一个圆孔里。reverse需要的是Apple,而不是Orange。糟糕的事情可能会发生!

顺便说一下:那么为什么将Apple赋值给声明为Fruit的变量却可以呢?(reverse返回一个AppleFruit f = reverse(re);是合法的)。因为AppleFruit。如果它被声明为更具体的Apple并且返回类型是更一般的Fruit,那么这里就会有问题了。(如果reverse返回FruitApple a = reverse(re);将是非法的。)

如果你没有听懂这个隐喻,就用List代替Fruit,用ArrayList代替Apple,再读一遍上面的内容。ListFruit,是描述抽象概念的一般方式。ArrayListApple,是抽象概念的具体实现方式。(LinkedList也可以是Orange。)

一般而言,你应该将事物声明为最一般的东西,以获得所需的功能。下面这个变更应该可以解决你的问题。

public List<Integer> reverse(List<Integer> list) {

我们正在使用一种List形式的Integer,并返回一种List形式的Integer


哦,好的。我明白了。非常感谢!我喜欢你可爱的例子! - beepretty

10
您正在使用特定的List接口实现作为reverse函数的返回类型(即ArrayList)。这将强制您返回一个ArrayList,但是您将其定义为List
要理解,请尝试更改构造部分以使用实现了ListLinkedList
List<Integer> newList = new LinkedList<Integer>();

这个结构是有效的,但现在我们尝试从返回一个 ArrayList 的函数中返回一个 LinkedList。由于它们之间没有关系,这毫无意义(但请注意:它们都实现了 List 接口)。

因此,您有两个选择:

通过强制使用 ArrayList 来使实现更加具体:

ArrayList<Integer> newList = new ArrayList<>();

或者更好的是,通过改变函数的返回类型(任何“List”都可以插入)使实现更加通用:
public List<Integer> reverse(List<Integer> list){

非常感谢!非常有用! - beepretty

2

这是因为你的结果变量类型是List,但你的方法需要一个ArrayList。 尝试使用:

List<ArrayList<Integer> result = new ArrayList<>();

或者更改您的函数为:

public List<Integer> reverse(List<Integer> list){...

好的,明白了。感谢你非常简单而清晰的回答! - beepretty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接