使用Arrays转数组成为List后,不能调用add(...)和remove(...)方法,此时如果调用就会抛出UnsupportedOperationException异常

原因

其实Arrays.asList(...)转成的List不是java.util包下面的ArrayList,而是一个内部静态类ArrayList。

asList(T... a)方法

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

ArrayList内部类

    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 = Objects.requireNonNull(array);
} @Override
public int size() {
return a.length;
} @Override
public Object[] 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;
} @Override
public E get(int index) {
return a[index];
} @Override
public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
} @Override
public int indexOf(Object o) {
E[] a = this.a;
if (o == null) {
for (int i = 0; i < a.length; i++)
if (a[i] == null)
return i;
} else {
for (int i = 0; i < a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
} @Override
public boolean contains(Object o) {
return indexOf(o) != -1;
} @Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(a, Spliterator.ORDERED);
} @Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
for (E e : a) {
action.accept(e);
}
} @Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
E[] a = this.a;
for (int i = 0; i < a.length; i++) {
a[i] = operator.apply(a[i]);
}
} @Override
public void sort(Comparator<? super E> c) {
Arrays.sort(a, c);
}
}

可以看到,ArrayList继承了AbstractList,内部还是通过数组持有元素。它与java.util下面的ArrayList不同的是,后者使用的是动态数组实现弹性增删等,而这里的ArrayList使用的是固定数组。因此,可以理解Arrays的内部类实现的List只是一个穿着List马甲的数组。他让数组拥有了集合的部分特性,而对于元素操作的支持和数组差不多。

而且内部类也没有重写add(...)和remove(...)方法等,因此他直接继承了AbstractList里面的add和remove方法

我们再看AbstractList的代码:

    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异常

解决方法

想要全部的List特性,可以将现有的数组元素转储到一个真正的java.util下面的List里面

ArrayList newList = new ArrayList<>(Arrays.asList(E[] arr));

小结

Arrays提供的转List方法,作为一个临时Collection容器是很便捷的,我们可以将它作为被其他集合操作的对象。但是如果我们期待像一个真正的List一样去使用它,结果表明并没什么卵用

参考

数组转换为List(Arrays.asList)后add或remove出现UnsupportedOperationException

ArrayList调用remove(int index)抛出UnsupportedOperationException问题分析以及解决记录的更多相关文章

  1. List 调用 remove 方法时抛出 java.lang.UnsupportedOperationException 异常原因

    原因 使用 Arrays.asList(arr) 转换的 List 并不能进行 add 和 remove 操作.       Arrays.asList(arr) 返回的类型是 Aarrays$Arr ...

  2. ArrayList调用remove方法需要注意的地方

    ArrayList中有remove 方法和 removeAll方法, ArrayList中不仅继承了接口Collection中的remove方法,而且还扩展了remove方法. Collection中 ...

  3. 执行ArrayList的remove(object)方法抛异常?

    简介 或许有很多小伙伴都尝试过如下的代码: ArrayList<Object> list = ...; for (Object object : list) { if (条件成立) { l ...

  4. Android之com.nostra13.universalimageloader加载图片抛出OutOfMemroyError错误的多种解决办法

    com.nostra13.universalimageloader是用来加载图片非常好的框架,但是也有问题,一旦图片过多的话,很容易就会提示OutOfMemroyError错误,也就是内存溢出的问题, ...

  5. Android ADT插件更新后程序运行时抛出java.lang.VerifyError异常解决办法

    当我把Eclipse中的 Android ADT插件从21.1.0更新到22.0.1之后,安装后运行程序抛出java.lang.VerifyError异常. 经过调查,终于找到了一个有效的解决办法: ...

  6. [SQL SERVER] - 还原数据库备份(SQL脚本),抛出 "System.OutOfMemoryException" 异常之解决

    背景 在 Microsoft SQL Server 2016 的查询窗体中,直接还原备份数据库的 SQL 脚本(99MB),抛出 Cannot execute script 异常: 原因 相关资料说: ...

  7. windows下安装composer抛出Composer\Downloader\TransportException异常解决办法

    1. 把默认的 secure-http 改成false composer config -g secure-http false 2. 修改配置文件 #修改全局文件(推荐) composer conf ...

  8. IE8下ckeditor无法正常使用,提示"例外被抛出且未被接住"的解决办法

    <script language="javascript" src="ckeditor/ckeditor.js"></script> & ...

  9. java.lang.UnsupportedOperationException 异常分析

    今天将一个数组转换成 List 然后进行 remove 操作时却抛出 java.lang.UnsupportedOperationException 异常. String pattern = &quo ...

随机推荐

  1. scss-声明变量与引用

    一.变量的声明 使用$符号可以标识一个变量 $bg-color: #FFFFFF; 二.变量的引用: 变量的引用有一个原则,那就是标准css属性值存在的地方,变量就可以存在. 当编译成css文件的时候 ...

  2. Python爬虫之三种数据解析方式

    一.引入 二.回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需 ...

  3. 【Android】2.0 Android开发环境的搭建——Eclipse

    1.0 eclipse,这可不算谷歌开发的,是IBM公司开发的,而且是Java语言写的 2.0 eclipse怎么下.百度“eclipse”,进入eclipse官网 然后,瞎几把下吧……,实在不行百度 ...

  4. The eighteen day

    27th Nov 2018 Setting goals is the first step in turning the invisible into the visiable   ---Tony R ...

  5. Ubuntu16.04安装Docker1.12+开发实例+hello world+web应用容器

    本次主要是详细记录Docker1.12在Ubuntu16.04上的安装过程,创建Docker组(避免每次敲命令都需要sudo),Docker常用的基本命令的总结,在容器中运行Hello world,以 ...

  6. ezdpl Linux自动化部署实战

    最近把ezdpl在生产环境中实施了,再加上这段时间的一些修改,一并介绍一下. 再次申明: ezdpl不是开箱即用的,需要根据自己的应用环境定制.对初学者来说使用起来反倒困难更多.风险更大. 它不是一个 ...

  7. hibernate基础配置

    数据库表名和类名 一致 注解:可写可不写: XML:可写可不写: <class name="Student"> 不一致 注解:  public class Teache ...

  8. JavaScript获取当前网页的源码

    通过 outerHTML document.documentElement.outerHTML 通过异步请求 $.get(window.location.href,function(res){ con ...

  9. 4.Zabbix 3.0 案例

    请查看我的有道云笔记: http://note.youdao.com/noteshare?id=2807c0910cd63d309e1462128a31ae0e&sub=241A94E5717 ...

  10. SAP成都研究院许聚龙:Hello, Coresystems!

    Jerry的前一篇文章<SAP成都研究院数字创新空间沟通S/4HANA和C/4HANA的智能服务演示视频和Coresystems分享预告>已经提到,接下来会由SAP成都研究院数字创新空间的 ...