繁体   English   中英

错误:类型不匹配:无法从列表转换<Integer>到 ArrayList<Integer>

[英]Error : Type mismatch: cannot convert from List<Integer> to ArrayList<Integer>

package set01;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class DFTList {
    static List<Integer>[]   list;
    static boolean[] visited;
    
    public DFTList(int nodes) {
        list = new ArrayList[nodes];
        visited = new boolean[nodes];
        for(int i=0;i<nodes;i++) {
           list[i] = new ArrayList<>();
        }
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter no. of nodes : ");
        int nodes = scan.nextInt();
        DFTList obj = new DFTList(nodes);
        System.out.println("Enter no.of vertex : ");
        int vertex = scan.nextInt();
        
        
        for(int i=0;i<vertex;i++) {
            int v1 = scan.nextInt();
            int v2 = scan.nextInt();
            list[v1].add(v2);
            list[v2].add(v1);
        }
        
        solve(0);
    }
    
    public static void solve(int a) {
        visited[a] = true;
        ArrayList<Integer> l = list[a];
    }

}

在上面的代码片段中,在DFTList构造函数中,我在ArrayList的所有索引处插入了ArrayList对象。 但是当我尝试在solve方法中检索相同的对象并将其存储在相同的引用下时,我遇到了一个错误,指出“类型不匹配:无法从 List 转换为 ArrayList”。 为什么会出现这个错误?

list被声明为List<Integer>[] (读作:整数列表的数组)。 每个元素中的值实际上是一个ArrayList的事实是无关紧要的 - 就编译器而言,每个元素都是一个List

您可以显式向下转换数组访问:

ArrayList<Integer> l = (ArrayList<Integer>)list[a];

或者,更惯用的是,如果您不依赖ArrayList没有出现在List接口中的任何特定方法,您可以将l声明为List<Integer>

List<Integer> l = list[a];

list变量是一个List<Integer>[] ,这意味着任何类型的ListArrayListLinkedList等)都可以存储在其中。 当从这个列表中检索一个元素时,Java 编译器只知道它是某种类型的List 它不知道List的特定类型(即使您作为程序员知道您只在数组中存储ArrayList项)。 因此, ArrayList<Integer> l = list[a]是编译失败,因为编译器不能保证从数组中检索到的元素是ArrayList而不是不同的List类型。

有几种方法可以解决这个问题。 假设您想将list保留为数组,最惯用的方法是将其类型更改为List<Integer>[]而不是ArrayList<Integer>[] 由于您没有使用任何特定于ArrayList方法或其他 API,因此List接口是这种类型的更好选择。

    public static void solve(int a) {
        visited[a] = true;
        List<Integer> l = list[a];
    }

另一种不太惯用的方法是将list变量的类型从List<Integer>[]更改为ArrayList<Integer>[] 此更改将导致您的变量分配按照已经编写的方式工作。

public class DFTList {
    static ArrayList<Integer>[] list;
    ...
}

当您拥有接口类型数组(在本例中为List<Integer> )时,您可以使用的最后一种方法是在将元素存储到变量时将其转换为具体类型。 这基本上是在告诉编译器您作为开发人员知道该元素属于该子类型,因此即使它不能保证分配,它也会允许它发生。 这种方法推迟了类型检查——确保ListArrayList子类型——直到代码实际运行(在运行时)。 如果在运行代码时存储的元素是ArrayList以外的子类型(例如,如果它是LinkedList ),那么 Java 将抛出ClassCastException,因为无法分配给ArrayList

像这样的转换并不理想,因为它消除了编译器对所有使用的类型在运行时都有效的保证。 然而,有时它是必要和适当的。

    public static void solve(int a) {
        visited[a] = true;
        ArrayList<Integer> l = (ArrayList<Integer>) list[a];
    }

你在把 C++ 和 Java 混在一起!!

检查以下可重现的代码:

    public class DFTList {
    static List<Integer>[]   list;
    static boolean[] visited;
    
    public DFTList(int nodes) {
        list = new ArrayList[nodes];
        visited = new boolean[nodes];
        for(int i=0;i<nodes;i++) {
           list[i] = new ArrayList<>();
        }
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter no. of nodes : ");
        int nodes = scan.nextInt();
        DFTList obj = new DFTList(nodes);
        System.out.println("Enter no.of vertex : ");
        int vertex = scan.nextInt();
        
        
        for(int i=0;i<vertex;i++) {
            int v1 = scan.nextInt();
            int v2 = scan.nextInt();
            list[v1].add(v2);
            list[v2].add(v1);
        }
        
        solve(0);
    }
    
    public static void solve(int a) {
        visited[a] = true;
        List<Integer> l = list[a];
    }    
}

注 0

java中没有类似概念的pointer ,因此以下代码段会为您提供编译时错误:

 * list[i] = new ArrayList<>();

注 1

您正在将List接口分配给l类型,因此请使用以下语法。

   List<Integer> l = list[a];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM