Java将通用LinkedList转换为通用数组

时间:2010-09-01 12:15:46

标签: java generics

首先让我们说我有一个LinkedList<String>

我可以通过toArray()轻松将其转换为数组。即。

LinkedList<String> strList = new LinkedList<String>();
String[] strArray = strList.toArray(new String[0]);

但是我们说我有LinkedList<T> 然后我下面的代码:

LinkedList<T> tList = new LinkedList<T>();
T[] strArray = tList.toArray(new T[0]);

我得到无法创建T 的通用数组错误消息。

我该如何解决这个问题?

特别是在我的班级中我有LinkedList<AbstractNode<T>> nodes,我正在尝试实现一个getAll()方法,该方法将所有节点作为数组返回。
谢谢!

注意PéterTörök的答案为我的问题提供了正确的答案,但对于我来说,简单地返回一个ArrayList而不是像Bar所提到的那样,最终平滑了我的代码。
Note2 在看了我的代码后,我甚至不确定是否需要进行任何转换,LinkedList对于我试图做的事情很好......: - /

2 个答案:

答案 0 :(得分:13)

类库中使用的解决方法是(使用未经检查的强制转换)

public <T> T[] toArray(List<T> list, T[] a) {
  if (a.length < list.size()) {
    a = (T[])java.lang.reflect.Array.newInstance(
        a.getClass().getComponentType(), list.size()));
  }
  return list.toArray(a);
}

或者,使用Class参数而不是数组:

public <T> T[] toArray(List<T> list, Class<T> k) {
     return list.toArray(
          (T[])java.lang.reflect.Array.newInstance(k, list.size()));
}

来自Java Generics and Collections,第6.4-5章。

  

无法创建通用数组是Java中最严重的限制之一。因为它太烦人了,所以值得重申它发生的原因:通用数组是有问题的,因为泛型是通过擦除来实现的,但是擦除是有益的,因为它可以简化进化。

     

最佳解决方法是优先使用集合框架中的ArrayList或其他类,而不是数组。我们在2.5节讨论了集合类和数组之间的权衡,并且我们注意到在许多情况下集合比数组更可取:因为它们在编译时捕获更多错误,因为它们提供了更多操作,并且因为它们在表示方面提供了更大的灵活性。到目前为止,数组提供的问题的最佳解决方案是“只说不”:使用集合优先于数组。

     

有时这不起作用,因为出于兼容性或效率的原因需要一个数组。集合框架中出现了这种情况:为了兼容性,方法toArray将集合转换为数组[...]

     

[...]将一个集合转换为一个数组的天真方法是行不通的。我们可能尝试的第一个修复是添加一个未经检查的强制转换,但我们很快就会看到这会导致更复杂的问题。正确的解决方案需要我们求助于反思。

答案 1 :(得分:1)

由于Java generic实际上是用类型object替换你的T并转换为在编译时解析的具体类型,因此可以创建List<T>,但不能创建T[]。 (第一个是对象列表,第二个是未知的) 好反射可以让你做很多丑陋的黑客攻击。你可以使用它们。我个人只有在没有其他方法可以做的时候才使用它们。我不喜欢运行时错误。

但我的问题是:您真的需要T[],为什么不使用ArrayList<T>