所以我编写了一个通用的邻接列表,我的代码没有编译错误,但是当我运行我的测试时,我得到了相同的运行时错误:
java.lang.ClassCastException: [[Ljava.lang.Object; cannot be cast to [[Lds.Graph.Edge;
at ds.TheAdjacencyMatrix.AdjacencyMatrix.<init>(AdjacencyMatrix.java:86)
at ds.TheAdjacencyMatrix.AdjacencyMatrix.<init>(AdjacencyMatrix.java:63)
at ds.TheAdjacencyMatrix.AdjacencyMatrix.<init>(AdjacencyMatrix.java:73)
at ds.Graph.Test.TheAdjacencyMatrixTest.testAddVertex(TheAdjacencyMatrixTest.java:33)
错误发生在我将2d对象数组转换为E [] [] type
的行的构造函数中邻接矩阵的相关代码是::
public class AdjacencyMatrix<T, E extends Edge>
implements AdjacencyMatrixInterface<T, E>, Graph<T, E> {
//~Constants----------------------------------------------
private static final int DEFAULT_SIZE = 10;
//~Data Fields--------------------------------------------
/**
* Int matrix that holds edge weights in weighted graphs.
* A 1 in a directed graph indicates an edge, a 0 indicates no edge.
*/
private E[][] matrix;
/**
* Array of elements contained in the graph.
* Elements correspond to the same indices as they do in the adjacency matrix of edges.
*
* i.e. matrix[4][5] is an edge from 4 to 5,
* elements[4] is the element at 4, elements[5] is the element at 5
*/
private T[] elements;
/**
* The maximum number of vertices in the adjacency matrix.
*/
private int size;
/**
* The current number of vertices in the graph.
*/
private int numVertices;
/**
* Indicates whether the graph is directed or not. True if directed, false otherwise.
*/
private boolean directed;
//~Constructors--------------------------------------------
/**
* Initializes the adjacency matrix to a size of 10.
* Which means there are 10 vertices in the graph.
*/
public AdjacencyMatrix() {
this(DEFAULT_SIZE);
}
/**
* Initializes the adjacency matrix to a size of 10. There will be 10 vertices in the graph.
*
* @param directed true if the graph is to be a directed graph, false otherwise.
*/
public AdjacencyMatrix(boolean directed) {
this();
this.directed = directed;
}
/**
* Initializes the adjacency matrix to a size of size.
* There will be a maximum size of *size* vertices in the graph
*
* @param size the size of the adjacency matrix.
*/
@SuppressWarnings("unchecked")
public AdjacencyMatrix(int size) {
matrix = (E[][]) new Object[size][size];
elements = (T[]) new Object[size];
this.size = size;
numVertices = 0;
directed = false;
}
Edge类是一个抽象类,其代码在这里:
package ds.Graph;
/**
* An abstract Edge class which has methods
* getWeight()
* and
* setWeight(int weight).
* Used for a Graph data structure to abstract
* out the edges.
*
*
*
*/
public abstract class Edge implements Comparable<Edge> {
/**
* Sets the weight of the edge to the passed in weight.
*
* @param weight the weight of the edge.
*/
public abstract void setWeight(int weight);
/**
* Gets the weight of the edge.
*
* @return the edge weight.
*/
public abstract int getWeight();
}
EDIT ::
因此,这是在运行时设置错误的代码行。 IntEdge只是一个继承自Edge的对象,它包含一个整数。
AdjacencyMatrixInterface<String, IntEdge> matrix = new AdjacencyMatrix<String, IntEdge>(false);
答案 0 :(得分:2)
简单地将该行改为
matrix = (E[][]) new Edge[size][size];
E
被删除到班级内部的上限。在这种情况下,E
的上限为Edge
。因此它会尝试转换为Edge[][]
。
此外,您必须确保matrix
和elements
不会分别以E[][]
和T[]
的形式向外界公开,因为它们并非属于这些类型。但只要你只在课堂上使用它们,就没有问题。
答案 1 :(得分:1)
问题是Object [] []不是Edge [] []的实例。你无法像那样投射你的物体。
new Object[][] {} instanceof Edge[][] // => false
它与Object [] []的另一种方式实际上是Edge [] []
的超类new Edge[][] {} instanceof Object[][] // => true
此外,根据Java Language Specification
数组类型的直接超类是Object。每个数组类型都实现了Cloneable和java.io.Serializable接口。
修改强>
另外,as Rahul Bobhate pointed out,使用Java Collections Framework会更好,因为它旨在使用泛型。所有array-based解决方法均为are pretty ugly。
答案 2 :(得分:0)
这不对,你必须得到未经检查的投射警告:
matrix = (E[][]) new Object[size][size];
elements = (T[]) new Object[size];
您需要显式传递数组实例,因为通用信息在运行时被擦除(这意味着在运行时执行的代码将是matrix = new Object[][]
)
您可以使用以下构造函数:
public class AdjacencyMatrix<T, E extends Edge>
implements AdjacencyMatrixInterface<T, E>, Graph<T, E> {
E[][] matrix;
T[] elements;
public AdjacencyMatrix(int size, E[][] matrix, T[] elements) {
this.matrix = matrix;
this.elements = elements;
}
}
答案 3 :(得分:0)
您无法将Object
的数组转换为E
。虽然它会编译,但它会在运行时导致ClassCastException
。您只能转换兼容的引用类型。由于E
数组和Object
数组之间没有任何关联,JVM将无法将Object
数组转换为E
数组。< / p>
您可以使用List而不是数组。您可以将矩阵定义为List
List
,如下所示:
private List<List<E>> matrix;
private List<T> elements;
然后,您可以轻松地在构造函数中初始化matrix
:
public AdjacencyMatrix(int size) {
matrix = new ArrayList<List<E>>(size);
for(int i=0; i<size; i++)
{
t.add(new ArrayList<E>());
}
elements = new ArrayList<T>(size);
this.size = size;
numVertices = 0;
directed = false;
}
然后,您可以按如下方式访问列表中的元素:
E e = matrix.get(0).get(1);
这将获取第一个列表中的第二个元素。
答案 4 :(得分:-1)
原因是因为即使E是Object的子类,E []也不是Object []的子类。数组具有平坦的类层次结构,因此不能相互投射。
[编辑]
我错了(thx评论)。实际上,数组有一个类型层次结构(参见http://etutorials.org/cert/java+certification/Chapter+6.+Object-oriented+Programming/6.5+Completing+the+Type+Hierarchy/)。正确地指出,您正在尝试将超类型实例转换为子类型,这也不适用于任何其他Java对象。