前言
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,通过源码应该对该过程有个清楚的认识。