如果这是一个常见的问题,我很难在任何地方找到它,但我正处理的是基本上是级联类型的问题。
public class Graph<E> {
private LinkedList<Node<E>> nodes;
public Graph() {
this.nodes = new LinkedList<>();
}
public E[] getNodes() {
ArrayList<E> list = new ArrayList<>();
for (Node<E> node : nodes)
list.add(node.getObject());
return list.toArray(new E[0]); // any way to make this line work?
}
// other important stuff
}
我想做这样的事情,但是我无法以这种方式实例化通用数组。 getNodes()返回节点的内容,而不是节点本身,但我无法弄清楚如何。
我认为由Graph泛型定义的Node泛型意味着Node类总是与Graph类具有相同的类型。那不是这样吗?
Node类看起来像
public class Node<E> {
private LinkedList<Edge> edges;
private E obj;
public E getObject() {
return obj;
}
// other useful stuff
}
感谢您的帮助!
编辑:现在需要的只是使返回的数组成为正确的类型。有没有办法从具有泛型类型赋值的ArrayList中获取数组?
答案 0 :(得分:1)
您需要在getThings
方法中使用某种形式的E具体化。
如果要保留getThings
的签名,可以添加construtor参数以提供实际的类E
。使用该类,您可以创建一个数组以传递给toArray(E[])
List<E>
方法
private final Class<E> type;
private final List<E> list;
public CustomClass(Class<E> type) {
this.type = type;
this.list = new ArrayList<>();
}
@SuppressWarnings("unchecked")
public E[] getThings() {
Object[] reference = (Object[]) Array.newInstance(type, list.size());
return (E[]) list.toArray(reference);
}
答案 1 :(得分:1)
其他人想出了一个不起作用的答案,但给了我一个最终起作用的想法,但他们也把它放在问题的评论部分,所以我将在这里重申并回答我自己的问题。
此代码可解决此问题。我或多或少地从他们的toArray(E[] a)
函数的ArrayList源代码中解除了逻辑(当然它的部分内容被删除了。)
@SuppressWarnings("unchecked")
public E[] getNodes(E[] a) {
int size = nodes.size();
// creates an empty array of the right size and type
E[] arr =(E[]) java.lang.reflect.Array
.newInstance(a.getClass().getComponentType(), size);
// fills that array with the correct data
for (int i = 0; i < size; i++)
arr[i] = nodes.get(i).getObject();
return arr;
}
查看ArrayList源代码,以便看到一些更进一步的逻辑,并以线程安全的方式完成相同的任务。