java.lang.UnsupportedOperationException

本文解析了使用Arrays.asList()转换数组为List时遇到UnsupportedOperationException的原因。深入探讨了该方法的内部实现,解释了为何不能使用修改集合的操作,并提出了解决方案。
摘要由CSDN通过智能技术生成

今天在做题,要实现遍历数组的时候同时删除指定元素,因为数组删除还要移动元素,所以就想Arrays.asList()转换成ArrayList使用迭代器删除。结果出现了java.lang.UnsupportedOperationException

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.remove(AbstractList.java:161)
	at java.util.AbstractList$Itr.remove(AbstractList.java:374)
	at reback_alg.alg_04.groupAnagrams1(alg_04.java:30)
	at reback_alg.alg_04.main(alg_04.java:14)

先说解决办法吧!很简单就重新new一个java.util.ArrayList!

ArrayList list=new ArrayList(Arrays.asList(new int[]{1,2,3}));

在这里插入图片描述

之前看过《阿里巴巴java开发手册》记得有一条就是:使用Arrays.asList()把数组转成集合的时候不能使用修改集合相关的方法!其实已经说得很清楚了!当时只是过了印象,今天看一下源码!

  /**
     * Returns a fixed-size list backed by the specified array.  (Changes to
     * the returned list "write through" to the array.)  This method acts
     * as bridge between array-based and collection-based APIs, in
     * combination with {@link Collection#toArray}.  The returned list is
     * serializable and implements {@link RandomAccess}.
     *
     * <p>This method also provides a convenient way to create a fixed-size
     * list initialized to contain several elements:
     * <pre>
     *     List&lt;String&gt; stooges = Arrays.asList("Larry", "Moe", "Curly");
     * </pre>
     *
     * @param <T> the class of the objects in the array
     * @param a the array by which the list will be backed
     * @return a list view of the specified array
     */
    @SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

    /**
     * @serial include
     */
    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {

1、方法的注释可看出,该方法作用是:传入指定的数组返回固定容量的list,提供了一个array到list的转换渠道。
2、方法返回的new ArrayList(a),而这个ArrayList其实是它的静态内部类,继承自AbastractList!

    /**
     * {@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();
    }


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

1、观察静态内部类的ArrayList常用的增删改方法发现它只重写了set(),并没有重写add()和remove(),而父类Abastract的这两个方法默认都是throw new UnsupportedOperationException(),
2、同时我们通过迭代器删除其实也是调用态内部类的ArrayList的remove()方法,因此就出现了文章开头的遇到的问题。

但是为什么要这么设计呢?为什么不直接使用java.util.ArrayList呢?

正如阿里巴巴的开发手册所说这体现适配器模式,只是一个转换接口,本质是还是一个数组。引用不变,如果原数组发生改变,转换后的List也会改变!

	 String[] strs = {"1", "2", "3"};
	 List<String> strs2 = Arrays.asList(strs);
	 //strs2的元素也会随之改变
	 strs[0]="0";
	
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值