0

为什么需要分配一个可以保存集合值的数组并将其传递给toArray(T [])该集合的方法?我知道有一种toArray()方法不需要预先分配的数组,但是这种方法返回的 Object[] 绝对不好。我也想避免类型转换。

例子:

Set<String> strings = new HashSet<>();
// put some values in it
String[] stringArr = strings.toArray(/* preallocated array, why? */);

假设我使用泛型(无论如何其他一切都是不好的做法),使用的集合类本身应该有足够的信息来为我完成这项工作。它可以做这样的事情:

public someCollection<T> {
...
    public T[] toArray() {
        T[] arr = new T[this.length];
        // fill the array with the collection values
        return arr;
    }
}

问题在哪里,如果我没有弄错,这应该很容易在默认集合类中实现。

4

3 回答 3

4

Java 泛型使用类型擦除,这意味着类型参数仅在编译时存在

在运行时,代码不知道是什么T,所以它不能创建一个new T[].

于 2013-11-08T13:46:22.617 回答
1

为什么需要分配一个可以保存集合值的数组并将其传递给该集合的 toArray(T []) 方法?

它不是。如果你愿意,你可以这样做,但同样你也可以传入一个空数组。因此,文档说明:

如果集合适合指定的数组,则在其中返回。否则,将使用指定数组的运行时类型和此集合的大小分配一个新数组。

你必须传递一些东西,因为如果需要,数组的执行时类型将用于创建另一个相同类型的数组。由于类型擦除,使用不会创建new T[...]正确执行时类型的数组。有关更多详细信息,请参阅Java 泛型常见问题解答,特别是有关具体参数化类型的数组的部分。

于 2013-11-08T13:47:30.893 回答
0

其他人完美地回答了您的主要问题以及为什么您的第二个代码块是不可能的。

我同意你的观点 Collection.toArray 方法并不完美,应该在 JRE 的未来版本中进行改进。我认为这要归功于 Java 8 中引入的防御方法。

实现它的一种方法可以是:

public someCollection<T> {
    ...
    public T[] toArray(Class<T> c) {
        T[] arr = Array.newInstance(c, getSize());
        // fill the array with the collection values
        return arr;
    }
}

另一种方式是 Collection 子类保存它们包含的类型(类),就像CheckedCollections一样,并在 toArray 方法上使用它,因此您不必提供任何参数。

于 2013-11-08T14:06:18.817 回答