通用的 for-each 循环有困难
Difficulty with generic for-each loop
我在编译 foreach 循环时遇到问题。我很确定这是我的泛型处理的问题,因为错误是对象兼容性问题。我已经搜索了解决方案,但找不到任何解决问题的方法。
这是定义 Iterable adjList 的代码。
public class Graph<V,E> {
private SinglyLinkedList<Vertex<V>> vertices = new SinglyLinkedList<>();
protected class Vertex<V> {
private SinglyLinkedList<Edge<E>> adjList = new SinglyLinkedList<>();
public void addEdge(Edge<E> e) {adjList.addLast(e);}
public Iterable<Edge<E>> adjList() {
return (SinglyLinkedList<Edge<E>>) adjList;
}
}
public Iterable<Edge<E>> edges(Vertex<V> v) {
return v.adjList;
//... Edge<E> is also a nested class
public Iterable<Vertex<V>> vertices() {return vertices;}
}
adjList 实际上是可迭代的,因为 SinglyLinkedList 是:
public class SinglyLinkedList<T> implements Iterable<T> {
//...
private class ListIterator implements Iterator<T> {
// ... next(), hasNext()
}
public Iterator<T> iterator() {return new ListIterator();}
}
此迭代器在其他情况下工作正常,包括其他 foreach 循环。这是它不起作用的地方(来自不同 class 的主要方法):
Graph<String, Integer> testgraph = createGraph("testgraph.txt");
//createGraph add some vertices and edges to testgraph
for (Vertex v : testgraph.vertices()) {
for (Edge e : testgraph.edges(v)) { //<--- problem here
System.out.print(e.getElement());
}
}
}
错误是"incompatible types: Object cannot be converted to Graph.Edge."
问题: 为什么 testgraph.edges(v) 返回对象列表而不是边?我真的很茫然。
此外,
for (Edge e : v.adjList())
也不起作用,同样的错误,并且在 Edge 之后在菱形括号中添加 "Integer" 也无法编译。这确实有效,但我真的想避免这种可怕的转换:
for (Edge e : ((Graph<String,Integer>.Vertex<String>)v).adjList())
非常感谢任何想法。
您使用的 Vertex
和 Edge
没有任何参数化,使它们有效 Vertex<Object>
和 Edge<Object>
.
public Iterable<Edge<E>> edges(Vertex<V> v) {
return v.adjList;
}
Edge
和 Vertex
都需要指定 Type
。
for (Edge<Integer> e : ((Graph<String,Integer>.Vertex<String>)v).adjList())
以上是不是可怕的转换,它们是泛型所期望的类型。
你有两个选择:
要么在所有地方指定类型,要么在任何地方不指定它们,完全删除它们。
问题是您将 Vertex<V>
和 Edge<E>
声明为 Graph<V,E>
的内部 class。这意味着 Vertex
的每个实例都绑定到参数化 class Graph
的实例。因此,当您尝试在 Graph
实例之外编写 Vertex<Integer>
时,对于 Graph
的原始类型,这意味着 Graph.Vertex<Integer>
。这就是编译器抱怨的原因。
您的选择是:
- 将 class 声明为
Vertex<V>
和 Edge<E>
为 static
。然后你就可以写成 Vertex<String>
或 Edge<Integer>
.
- 从
Vertex
和 Edge
中删除类型参数并将它们称为 Graph<String,Integer>.Vertex
和 Graph<String,Integer>.Edge
我在编译 foreach 循环时遇到问题。我很确定这是我的泛型处理的问题,因为错误是对象兼容性问题。我已经搜索了解决方案,但找不到任何解决问题的方法。
这是定义 Iterable adjList 的代码。
public class Graph<V,E> {
private SinglyLinkedList<Vertex<V>> vertices = new SinglyLinkedList<>();
protected class Vertex<V> {
private SinglyLinkedList<Edge<E>> adjList = new SinglyLinkedList<>();
public void addEdge(Edge<E> e) {adjList.addLast(e);}
public Iterable<Edge<E>> adjList() {
return (SinglyLinkedList<Edge<E>>) adjList;
}
}
public Iterable<Edge<E>> edges(Vertex<V> v) {
return v.adjList;
//... Edge<E> is also a nested class
public Iterable<Vertex<V>> vertices() {return vertices;}
}
adjList 实际上是可迭代的,因为 SinglyLinkedList 是:
public class SinglyLinkedList<T> implements Iterable<T> {
//...
private class ListIterator implements Iterator<T> {
// ... next(), hasNext()
}
public Iterator<T> iterator() {return new ListIterator();}
}
此迭代器在其他情况下工作正常,包括其他 foreach 循环。这是它不起作用的地方(来自不同 class 的主要方法):
Graph<String, Integer> testgraph = createGraph("testgraph.txt");
//createGraph add some vertices and edges to testgraph
for (Vertex v : testgraph.vertices()) {
for (Edge e : testgraph.edges(v)) { //<--- problem here
System.out.print(e.getElement());
}
}
}
错误是"incompatible types: Object cannot be converted to Graph.Edge."
问题: 为什么 testgraph.edges(v) 返回对象列表而不是边?我真的很茫然。
此外,
for (Edge e : v.adjList())
也不起作用,同样的错误,并且在 Edge 之后在菱形括号中添加 "Integer" 也无法编译。这确实有效,但我真的想避免这种可怕的转换:
for (Edge e : ((Graph<String,Integer>.Vertex<String>)v).adjList())
非常感谢任何想法。
您使用的 Vertex
和 Edge
没有任何参数化,使它们有效 Vertex<Object>
和 Edge<Object>
.
public Iterable<Edge<E>> edges(Vertex<V> v) {
return v.adjList;
}
Edge
和 Vertex
都需要指定 Type
。
for (Edge<Integer> e : ((Graph<String,Integer>.Vertex<String>)v).adjList())
以上是不是可怕的转换,它们是泛型所期望的类型。
你有两个选择:
要么在所有地方指定类型,要么在任何地方不指定它们,完全删除它们。
问题是您将 Vertex<V>
和 Edge<E>
声明为 Graph<V,E>
的内部 class。这意味着 Vertex
的每个实例都绑定到参数化 class Graph
的实例。因此,当您尝试在 Graph
实例之外编写 Vertex<Integer>
时,对于 Graph
的原始类型,这意味着 Graph.Vertex<Integer>
。这就是编译器抱怨的原因。
您的选择是:
- 将 class 声明为
Vertex<V>
和Edge<E>
为static
。然后你就可以写成Vertex<String>
或Edge<Integer>
. - 从
Vertex
和Edge
中删除类型参数并将它们称为Graph<String,Integer>.Vertex
和Graph<String,Integer>.Edge