java 集合与数组的互转方法,与源码分析

前言

   java数组与集合需要互相转换的场景非常多,但是运用不好还是容易抛出UnSupportedOperationException。下面讲解一下互转的方法,以及结合源码分异常产生的原因

集合转数组

   

  List<String> strList = new ArrayList<>(10);
        strList.add("aa");
        strList.add("bb");
        strList.add("cc");
        String[] strArray1 = new String[2];
        strList.toArray(strArray1);
        for (String st : strArray1) {
            System.out.println(st);
        }

上段代码的运行结果为

为什么数组中是空值呢,明明已经通过toArray()赋值了啊,我们去看一下源码

    public <T> T[] toArray(T[] a) {
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

可以明显的看到,当传入的数组的大小小于集合的大小时,会返回一个新创建的数组,不会执行arraycopy方法,所以会出现数组中元素为空的情况,看了源码之后,想必大家都知道该怎么做了,只要数组的大小能容纳下集合的大小即可。

     List<String> strList = new ArrayList<>(10);
        strList.add("aa");
        strList.add("bb");
        strList.add("cc");
        String[] strArray1 = new String[strList.size()];
        strList.toArray(strArray1);
        for (String st : strArray1) {
            System.out.println(st);
        }

上述代码运行结果为

数组转集合

 1  String[] strArray = new String[3];
 2         for (int i = 0; i<strArray.length; i++) {
 3             strArray[i] = "a"+i;
 4         }
 5         List<String> strList = new ArrayList<>(10);
 6         strList = Arrays.asList(strArray);
 7         strList.set(0,"a00");
 8         for (String str :strList) {
 9             System.out.println(str);
10         }
11         Thread.sleep(2000);
12         strList.remove(2);
13         strList.add("111");

在数组转为集合的时候,方法如上,编译通过,运行结果如下

可以明显的看到,我们在设置值与取值的时候是没有问题的,UnsupportedOperationException这个异常产生在对集合进行remove和add操作的时候,下面我们查看一下Arrays工具类中的asList() 源码

    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

可以看到,在Arrays类中,asList返回的是一个ArrayList对象,这就很奇怪了,既然是ArrayList对象,为什么不能进行add和remove操作呢,我们仔细看了该ArrayList对象才发现,此ArrayList是Arrays类

中的一个内部类,根据就近原则,asList()返回的实际上是该内部类对象,并非java.util下的ArrayList.

我们再看一下关系图

 

可以发现,内部类的ArrayList实则是没有add和remove方法,但是在调用的时候编译并没有报错,所以说实际上,该ArrayList对象调用的是父类AbstractList中的remove和add方法,接着我们继续去看AbstractList类中,这两个方法的源码

 
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }


    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

看到这里想必大家都明白了异常产生的源头。

总结

 数组和集合的互转非常简单,但是在使用的过程中应该注意到其中容易产生的 UnsupportedOperationException,通过源码应该对该过程有个清楚的认识。

   

原文地址:https://www.cnblogs.com/devise/p/10136643.html