Java之Arrays.asList(T...t)详解

学而时习之,不亦乐乎。

今天的主题是Arrays.asList(),返回的List(ArrayList),为什么不支持remove,add操作。

先上第一盘菜,跟着源码一步一步走

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

Arrays下的asList方法,返回的是一个ArrayList,发现此ArrayList非彼"ArrayList"。而是Arrays中一个私有静态内部类,划重点。

  private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        ...
    }

写一段代码来开始测试。

    public static void main(String[] args) {
        try {
            List<String> integers = Arrays.asList("1","2", "3", "4");
            System.out.println(integers.size());
            boolean result = integers.remove("2");
            System.out.println(integers.size());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

当调用remove("2"),由于此ArrayList没有重写,则去调用ArrayList---AbstractList---AbstractCollection的remove(Object)方法,看到会调用迭代器it的remove方法

    public boolean remove(Object o) {
        Iterator<E> it = iterator();
        if (o==null) {
            while (it.hasNext()) {
                if (it.next()==null) {
                    it.remove();
                    return true;
                }
            }
        } else {
            while (it.hasNext()) {
                if (o.equals(it.next())) {
                    it.remove();
                    return true;
                }
            }
        }
        return false;
    }

而it.remove(),则会调用实现类的AbstractList内部迭代器Itr的remove(),最终会调用AbstractList的remove(int)方法,

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.remove(lastRet);
                if (lastRet < cursor)
                    cursor--;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException e) {
                throw new ConcurrentModificationException();
            }
        }
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

AbstractList的remove(int),方法会直接抛出异常。

而且Arrays.asList()返回的时候,只能向上转型为LIst<Integer>,而不是Arrays的内部类ArrayList,静态私有的。

综上所述:Arrays.asList()返回的List(ArrayList)不能进行add,remove的原因就是,此ArrayList是java.util.Arrays下的,而不是java.util包下的,此ArrayList没有重写这个方法,不具备这个行为,调用remove时,父类里面会抛异常。

那实际中如何解决这个问题呢,进行remove,add呢,既然返回的是ArrayList,但是它和java.util下的ArrayList有共同的父类Collection,都实现了List接口,可以将Arrays.asList返回的ArrayList作为参数,传给java.util下的ArrayList带Collection参数的构造方法。

java.util下的ArrayList

   public ArrayList(Collection<? extends E> c) {
        Object[] a = c.toArray();
        if ((size = a.length) != 0) {
            if (c.getClass() == ArrayList.class) {
                elementData = a;
            } else {
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {
            // replace with empty array.
            elementData = EMPTY_ELEMENTDATA;
        }
    }

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值