Kavin_V
Kavin_V

Reputation: 33

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];
    }

}

In the above code snippet, At the DFTList constructor, I have inserted ArrayList object at all the indices of the array. But when I try to retrieve the same object at the solve method and store it under the same reference, I encountered an error stating that "Type mismatch: cannot convert from List to ArrayList". Why does this error occur?

Upvotes: 2

Views: 5918

Answers (3)

M. Justin
M. Justin

Reputation: 21367

The list variable is a List<Integer>[], which means that any type of List (ArrayList, LinkedList, etc.) could be stored in it. When retrieving an element from this list, all the Java compiler knows is that it's some type of List; it doesn't know the specific type of List (even though you as the programmer know that you're only storing ArrayList items in the array). Therefore, ArrayList<Integer> l = list[a] is a compilation failure because the compiler can't guarantee that the element retrieved from the array is an ArrayList and not a different List type.

There are a few ways to address this issue. Assuming you wanted to keep list as an array, the most idiomatic approach would be to change its type to List<Integer>[] instead of ArrayList<Integer>[]. Since you are not using any methods or other API specific to ArrayList, the List interface is a better choice for this type.

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

Another, less idiomatic approach would be to change the type of the list variable from List<Integer>[] to ArrayList<Integer>[]. This change would cause your variable assignment to work as already written.

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

The final approach you could use when you have an array of the interface type (List<Integer> in this case) would be to cast the element to the concrete type when assigning it to the variable. This is basically telling the compiler that you as the developer know the element is of that subtype, so even though it cannot guarantee the assignment, it will allow it to happen. This approach defers the type checking — ensuring the List is the ArrayList subtype — until the code is actually run (at runtime). If the stored element is a subtype other than ArrayList when the code is run (e.g. if it's a LinkedList), then Java will throw a ClassCastException since the assignment to ArrayList cannot happen.

Casting like this is not ideal, as it removes guarantees by the compiler that all types being used are guaranteed to be valid at runtime. However, there are times where it is necessary and appropriate.

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

Upvotes: 1

Mureinik
Mureinik

Reputation: 312259

list is declared as a List<Integer>[] (read: an array of Lists of Integers). The fact that the value in each element is actually an ArrayList is inconsequential - as far as the compiler is concerned, every element is a List.

You could either explicitly downcast the array access:

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

Or, more idiomatically, if you aren't relying on any specific method ArrayList has that isn't present in the List interface, you could declare l as a List<Integer>:

List<Integer> l = list[a];

Upvotes: 1

Papai from BEKOAIL
Papai from BEKOAIL

Reputation: 1539

you are mixing C++ with Java!!

check the following reproducable code:

    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];
    }    
}

Note 0

there is no pointer like concept in java therefore following snippet gives you compile time error:

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

Note 1

you are assigning List interface to l type therefore use below syntax.

   List<Integer> l = list[a];

Upvotes: 0

Related Questions