Reputation: 33
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
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
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
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];
}
}
there is no pointer
like concept in java therefore following snippet gives you compile time error:
* list[i] = new ArrayList<>();
you are assigning List
interface to l
type therefore use below syntax.
List<Integer> l = list[a];
Upvotes: 0