将ArrayList集合转换成数组

ArrayList集合转换成数组

以String类型为例,我们使用List接口的toArray()方法。

用法1:Object[] toArray();
用法2: T[] toArray(T[] a);

注意这里有两种写法,使用示例如下所示


        用法1
        List  stringList2 = new ArrayList<>();
        stringList2.add("A");
        stringList2.add("B");
        stringList2.add("C");
        Object[] objectArray  = stringList2.toArray();

        用法2
        List stringList = new ArrayList<>();
        stringList.add("A");
        stringList.add("B");
        stringList.add("C");
        String[] stringArray = stringList.toArray(new String[stringList.size()]);

 

再分析这两种写法的差异之前,我们先做一些知识铺垫

1、system.arraycopy方法的使用
它是一个native方法,他的作用是实现数组之间的复制操作。

public static native void arraycopy(Object src,  int  srcPos, Object dest, int destPos,  int length);

src:源数组; 
srcPos:源数组要复制的起始位置; 
dest:目的数组; 
destPos:目的数组放置的起始位置; 
length:复制的长度。

 2、ArrayList类中一些全局变量

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     * 我们都知道ArrayList的本质是动态数组,所以底层的elementData是一个Object数组
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).
     * List的大小
     * @serial
     */
    private int size;

下面开始讲解这两种toArray的底层原理

用法1:

    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

    //传入List的内容和大小
    public static  T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }


    //整体说一下这块儿的设计思路,如果传来的新数组是一个Object类型,则new一个Object类型的数组,
    //否则创建给定类型的数组。注意他们的长度都是List的长度。
    //最终执行native方法对数组进行拷贝
    public static  T[] copyOf(U[] original, int newLength, Class newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

用法2:


    public  T[] toArray(T[] a) {
        //如果需要转换的数组长度小于List的长度
        if (a.length < size)
            // 创建并返回一个新的数组
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        //否则直接将List的内容拷贝到a数组中    
        System.arraycopy(elementData, 0, a, 0, size);
        //如果要复制的新数组长度大于list的长度,那么将超过list长度后面的值设置为null
        if (a.length > size)
            a[size] = null;
        //返回新数组
        return a;
    }

    //同上所述
    public static  T[] copyOf(U[] original, int newLength, Class newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

 

注意一下坑

当你选择用法一的时候,注意强转的操作

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
    at com.jd.icity.metadata.controller.Main.main(Main.java:18)
原因是Object[] 数组不能强转成String[]数组;除非这个数组初始化的时候就指向了String[]数组。

可以这样操作
        List  stringList2 = new ArrayList<>();
        stringList2.add("A");
        stringList2.add("B");
        stringList2.add("C");
        Object[] objectArray  = stringList2.toArray();
        String[] object2StringArray = new String[objectArray.length];
        for(int i=0;i

 

你可能感兴趣的:(java基础,开发点滴)