【问题标题】:List<Integer> cannot be converted to ArrayList<Integer>List<Integer> 无法转换为 ArrayList<Integer>
【发布时间】:2015-07-31 20:26:11
【问题描述】:

在我的代码的开头,有:

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

为什么?

【问题讨论】:

  • re 是如何声明的?请记住,List 不是ArrayList,但恰恰相反。
  • List是接口,ArrayList是实现List接口的类之一。因此,任何 ArrayList 都是 List(即 ArrayList 可以隐式分配给 List),但反之则不然。将返回类型更改为 List,或将 newList 变量类型更改为 ArrayList。顺便把“return”移出循环体。
  • 不要使用原始类型ArrayList。使用new ArrayList&lt;&gt;(); 而不是new ArrayList();

标签: java list typeconverter


【解决方案1】:

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

Fruit re;

你有一个方法reverse,它的输入类型是Apple

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

我们有一个变量re,我们声明为Fruit,这意味着我们说它总是某种Fruit,可能是Apple,但也可能是Orange——甚至是@ 987654332@.

当您尝试将 Fruit 提供给采用 Apple 的方法时,编译器会阻止您,因为无法确定它 100% 是 Apple。比如……

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

哎呀!可以这么说,我们正在将一个方形钉子放入一个圆孔中。 reverse 接受 Apple,而不是 Orange。坏事可能会发生!

旁注: 那么为什么可以将Apple 分配给声明为Fruit 的东西呢? (reverse 返回 AppleFruit f = reverse(re); 是合法的。)因为 Apple Fruit。如果它被声明为更具体的Apple 并且返回类型是更通用的Fruit那么这里就会出现问题。 (如果reverse 返回FruitApple a = reverse(re); 将是非法的。)

如果您没有遵循这个比喻,Fruit 替换为 List 并将 Apple 替换为 ArrayList 并再次阅读以上内容。 ListFruit,一种描述抽象概念的通用方式。 ArrayListApple,抽象思想的具体实现。 (LinkedList 也可以是 Orange。)

一般来说,您希望将事物声明为您可以获得所需功能的最通用事物。进行以下更改应该可以解决您的问题。

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

我们正在采取某种ListIntegers 并返回某种ListIntegers。

【讨论】:

  • 哦,好的。我懂了。非常感谢你!我喜欢你可爱的例子!
【解决方案2】:

您正在使用List 接口的特定实现作为reverse 函数(即ArrayList)的返回类型。这会强制您返回 ArrayList,但您将其定义为 List

为了理解,尝试将构造部分更改为使用LinkedList,它也实现了List

List<Integer> newList = new LinkedList<Integer>();

这个构造是有效的,但现在我们尝试从返回 ArrayList 的函数中返回 LinkedList。这是没有意义的,因为它们不相关(但请注意:它们都实现了List)。

所以现在你有两个选择:

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

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

或者更好,通过改变函数的返回类型使实现更通用(可以插入任何List):

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

【讨论】:

  • 非常感谢!很有用!
【解决方案3】:

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

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

改变你的功能:

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

【讨论】:

  • 好的。知道了。感谢您非常简单但清晰的回答!
猜你喜欢
  • 2019-08-24
  • 2018-10-28
  • 1970-01-01
  • 1970-01-01
  • 2015-05-29
  • 2013-04-07
  • 2022-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多