Java数组转集合与集合转数组的坑
在Java中将数组转为集合,会用到Arrays.asList()的方法,然而,这个方法却与我们的预期期望存在一些出入,当用到asList方法将数组转化成List列表时,对得到的List列表进行add()和remove()操作, JVM会抛出异常:java.lang.UnsupportedOperationException异常
Arrays.asList返回的是同样的ArrayList,为什么就不能使用add和remove方法呢?
接下来我们来看一下Arrays.asList 源码
public static List asList(T... a) {
return new ArrayList<>(a);}复制代码
/**
* @serial include */private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{ private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { a = s.requireNonNull(array); } @Override public int size() { return a.length; } @Override public [] toArray() { return a.clone(); } @Override @SuppressWarnings("unchecked")复制代码
AbstractList源码:
复制代码
public abstract class AbstractList extends AbstractCollection implements List {
/** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */protected AbstractList() {}/** * Appends the specified element to the end of this list (optional * operation). * * <p>Lists that support this operation may place limitations on what * elements may be added to this list. In particular, some * lists will refuse to add null elements, and others will impose * restrictions on the type of elements that may be added. List * classes should clearly specify in their documentation any restrictions * on what elements may be added. * * <p>This implementation calls {@code add(size(), e)}. * * <p>Note that this implementation throws an * {@code UnsupportedOperationException} unless * {@ #add(int, ) add(int, E)} is overridden. * * @param e element to be appended to this list * @return {@code true} (as specified by {@ Collection#add}) * @throws UnsupportedOperationException if the {@code add} operation * is not supported by this list * @throws ClassCastException if the class of the specified element * prevents it from being added to this list * @throws NullPointerException if the specified element is null and this * list does not permit null elements * @throws IllegalArgumentException if some property of this element * prevents it from being added to this list */public boolean add(E e) { add(size(), e); return true;}/** * {@inheritDoc} * * @throws IndexOutOfBoundsException {@inheritDoc} */abstract public E get(int index);/** * {@inheritDoc} * * <p>This implementation always throws an * {@code UnsupportedOperationException}. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */public E set(int index, E element) { throw new UnsupportedOperationException();}/** * {@inheritDoc} * * <p>This implementation always throws an * {@code UnsupportedOperationException}. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */public void add(int index, E element) { throw new UnsupportedOperationException();}/** * {@inheritDoc} * * <p>This implementation always throws an * {@code UnsupportedOperationException}. * * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */public E remove(int index) { throw new UnsupportedOperationException();}复制代码
由源码可见,UnsupportedOperationException 是AbstractList抛出的,因为Arrays中的ArrayList并没有实现remove()和add()方法,所以抛出了异常。
所以说 Arrays.asList 返回的 List 是一个不可变长度的列表,此列表不再具备原 List 的很多特性,因此慎用 Arrays.asList 方法。
ArrayList中构造方法:
ArrayList(E[] array) {
a = s.requireNonNull(array); }看一段这样的代码:
复制代码
import java.util.Arrays;
import java.util.List;
public class Test2{
public static void main(String[] args) { int[] array = new int[]{1,2,3,4,5}; List list = Arrays.asList(array); System.out.println(list.size());}}
复制代码
Arrays 的内部类 ArrayList 构造方法接收的是一个泛型数组,即数组类型不能为基本类型,应该为其对应的包装类型(传即入引用类型),否则传入的基本类型的整个数组,将被编译器视为一个引用参数,
所以原始类型不能作为 Arrays.asList 方法的参数,否则会被当做一个参数
再来看看在Java中将集合转为数组,ArrayList提供了一个将List转为数组的一个非常方便的方法toArray。toArray有两个重载的方法:
@Override
public [] toArray() { return a.clone(); }复制代码
@Override
@SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass()); System.arraycopy(this.a, 0, a, 0, size); if (a.length > size) a[size] = null; return a; }复制代码
对于第一个重载方法,是将list直接转为 [] 数组;
第二种方法是将list转化为你所需要类型的数组,当然我们用的时候会转化为与list内容相同的类型。
若采用第一种toArray方法,是这样写:
复制代码
1 ArrayList list=new ArrayList();
2 for (int i = 0; i < 10; i++) {
3 list.add(""+i);
4 }
5
6 String[] array= (String[]) list.toArray();
复制代码
结果一运行,报错:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang. ; cannot be cast to [Ljava.lang.String;
第一个方法不能将 [] 转化为String[],我们需要修改为:
1 [] arr = list.toArray();
2 for (int i = 0; i < arr.length; i++) {
3 String e = (String) arr[i];
4 System.out.println(e);
5 }
建议用第二种方法:
复制代码
import java.util.ArrayList;
import java.util.List;
public class Test2{
public static void main(String[] args) { List<Integer> list = new ArrayList(); list.add(1); list.add(2); list.add(3); Integer[] array = new Integer[list.size()]; list.toArray(array); for (int i:array){ System.out.print(i+" "); }}}
复制代码
或者
set.toArray(new Integer[set.size()]);
set好处是去除重复元素
原文地址https://www.cnblogs.com/hetaoyuan/archive/2019/07/24/11236999.html
继续阅读与本文标签相同的文章
-
网站内部链接优化提高搜索排名
2026-05-23栏目: 教程
-
阿里云人脸识别门禁一体机怎么样?识别率高达99.9%
2026-05-23栏目: 教程
-
独立云虚拟主机 如何免费配置https加速呢?
2026-05-23栏目: 教程
-
分不清电商小程序模板和定制的区别?
2026-05-23栏目: 教程
-
ViewPager懒加载极致优化
2026-05-23栏目: 教程
