【发布时间】:2015-07-03 12:46:10
【问题描述】:
我无法编译一个 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 循环。这是它不起作用的地方(来自不同类的主要方法):
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());
}
}
}
错误是“不兼容的类型:对象无法转换为 Graph.Edge。”
问题: 为什么 testgraph.edges(v) 返回的是对象列表而不是边缘?我真的很茫然。
还有,
for (Edge e : v.adjList())
也不起作用,出现相同的错误,并且在 Edge 之后的菱形括号中添加“Integer”也无法编译。这确实有效,但我真的想避免这种可怕的演员阵容:
for (Edge e : ((Graph<String,Integer>.Vertex<String>)v).adjList())
非常感谢您的任何想法。
【问题讨论】:
-
您没有向我们展示所有代码并没有帮助 - 但基本上问题在于您使用的是原始类型。如果您可以缩短一个简短但完整的程序(使用
vertices()等)会有所帮助。 -
好的。我会尝试添加相关代码。您介意指出原始类型在哪里吗?我想我明白它们是什么,但我认为我在任何地方都使用了菱形括号。
-
您使用的是
Vertex和Edge,而不是(比如说)Vertex<String>和Edge<Integer>。 -
如果 Vertex 和 Edge 是 Graph
的内部类,对它们进行参数化有些多余。也许您打算制作 Vertex 和 Edge static 类。 -
@Misha 或者您可以从
Vertex和Edge中删除类型参数,以便它们使用V和E定义的Graph。您的静态类解决方案还需要添加E作为adjList的返回类型的类型参数才能工作。无论哪种方式,我们都需要更多代码来正确识别问题的根源。 :-)
标签: java generics foreach iterable