Java List< T> T [] toArray(T [] a)的实现 [英] Java List <T> T[] toArray(T[] a) implementation

查看:135
本文介绍了Java List< T> T [] toArray(T [] a)的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是看着List接口中定义的方法:< T> T [] toArray(T [] a)
,我有一个问题。为什么是通用的?因为这个事实,方法不是完整的类型安全的。以下代码片段编译,但会导致 ArrayStoreException

 列表< Integer> list = new ArrayList< Integer>(); 
list.add(1);
list.add(2);

String [] stringArray = list.toArray(new String [] {});

在我看来,如果toArray不是泛型的并且使用List类型参数,那会更好。 / p>

我写过玩具的例子,它可以通用:

 包装测试; 

import java.util.Arrays;

public class TestGenerics< E> {
private Object [] elementData = new Object [10];
private int size = 0;

public void add(E e){
elementData [size ++] = e;
}

@SuppressWarnings(unchecked)
//我从ArrayList中取出这个代码,但它不是通用的
public E [] toArray(E []) a){
if(a.length< size)
//创建一个新的运行时类型数组,但是我的内容:
return(E [])Arrays.copyOf(elementData ,size,a.getClass());
System.arraycopy(elementData,0,a,0,size);
if(a.length>大小)
a [size] = null;
返回a;


public static void main(String [] args){

TestGenerics< Integer> list = new TestGenerics< Integer>();
list.add(1);
list.add(2);
list.add(3);
//你不必做任何转换
Integer [] n = new Integer [10];
n = list.toArray(n);






$ b

是否有任何理由说明它是这样声明的?

解决方案

javadocs


<与toArray()方法一样,此方法充当
基于数组和基于集合的API之间的桥梁。此外,此方法允许
精确控制输出数组的运行时类型,并且在某些情况下可能会使用
来节省分配成本。


这意味着程序员可以控制它应该是什么类型的数组。



例如,对于 ArrayList< Integer> 而不是 Integer [] 数组可能需要 Number [] Object [] 数组。

此外,该方法还检查传递的数组如果你传入一个有足够空间存放所有元素的数组,那么 toArray 方法将重新使用该数组。这意味着:

  Integer [] myArray = new Integer [myList.size()]; 
myList.toArray(myArray);

  Integer [] myArray = myList.toArray(new Integer [myList.size()]); 

具有相同的效果,但效率高于

  Integer [] myArray = myList.toArray(new Integer [0]); 

作为后面的操作使用反射来检查数组类型,然后动态地构造一个正确类型的数组。通过首先传入正确大小的数组,反射不必用于在 toArray 方法内分配新数组。


I was just looking at the method defined in the List interface: <T> T[] toArray(T[] a) , and I have a question. Why is it generic? Because of that fact, method is not complete type-safe. The following code fragment compiles but causes ArrayStoreException:

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);

String[] stringArray = list.toArray(new String[]{});

It seems to me if toArray was not generic and took List type parameter, it would be better.

I have written toy example and it is ok witout generic:

package test;

import java.util.Arrays;

public class TestGenerics<E> {
    private Object[] elementData = new Object[10];
private int size = 0;

    public void add(E e) {
    elementData[size++] = e;
}

@SuppressWarnings("unchecked")
    //I took this code from ArrayList but it is not generic
public E[] toArray(E[] a) {
    if (a.length < size)
        // Make a new array of a's runtime type, but my contents:
        return (E[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

    public static void main(String[] args) {

    TestGenerics<Integer> list = new TestGenerics<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    //You don't have to do any casting
    Integer[] n = new Integer[10];
    n = list.toArray(n);
}
}

Is there any reason why it is declared that way?

解决方案

From the javadocs:

Like the toArray() method, this method acts as bridge between array-based and collection-based APIs. Further, this method allows precise control over the runtime type of the output array, and may, under certain circumstances, be used to save allocation costs.

This means that the programmer is in control over what type of array it should be.

For example, for your ArrayList<Integer> instead of an Integer[] array you might want a Number[] or Object[] array.

Furthermore, the method also checks the array that is passed in. If you pass in an array that has enough space for all elements, the the toArray method re-uses that array. This means:

Integer[] myArray = new Integer[myList.size()];
myList.toArray(myArray);

or

Integer[] myArray = myList.toArray(new Integer[myList.size()]);

has the same effect but is more efficient than

Integer[] myArray = myList.toArray(new Integer[0]);

as the latter operation uses reflection to check the array type and then dynamically construct an array of the right type. By passing in a correctly sized array in the first place, reflection does not have to be used to allocate a new array inside the toArray method.

这篇关于Java List&lt; T&gt; T [] toArray(T [] a)的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆