• Arrays.asList()你真的知道怎么用吗?


    发现问题

    前几天在看别人的项目的时候,发现一个问题,简单复现一下这个问题

    // 注意这是一个Integer对象的数组哦
    Integer[] arr = new Integer[]{9999,88,77};
    List list = Arrays.asList(arr);
    // 执行以下操作,有问题么?
    list.add(1);
    list.remove(0);
    

    好的,如果你觉得没错,和我刚开始的想法一致。在我没有认真学习这个asList方法时,天真的以为没有问题,顾名思义啊,就是把数组转换成List呗。

    // 恭喜,喜提报错,如果是这样测试该找你麻烦了,/(ㄒoㄒ)/~~ 
    Exception in thread "main" java.lang.UnsupportedOperationException
    	at java.util.AbstractList.add(AbstractList.java:148)
    	at java.util.AbstractList.add(AbstractList.java:108)
    	at TestForAsList.main(TestForAsList.java:13)
    

    废话不多说,我们直接进源码里面看看。

    @SafeVarargs
    @SuppressWarnings("varargs")
    public static  List asList(T... a) {
        return new ArrayList<>(a);  // 看起来没有任何异常,emm。然而呢,这个ArrayList并不是Java.util包下的ArrayList,而是一个在Arrays下实现的内部类。
    }
    

    image

    我们发现这个静态内部类里面并没有实现List的add和remove方法。那么子类将延用父类AbstractList的方法实现,这个继承应没有什么问题。

    // 我们进入这个父类的实现,发现了报错的根源。。
    public abstract class AbstractList extends AbstractCollection implements List {
        
    	public void add(int index, E element) {
            throw new UnsupportedOperationException();
        }
    
    
        public E remove(int index) {
            throw new UnsupportedOperationException();
        }
    }
    

    总结:

    究其原因,就是这个asList方法返回的是一个内部类,只实现了一些遍历以及更新的方法。下次使用它的时候需要注意一下。

    扩展知识点

    数组值的变化

    然后我就发现了这个很有意思的点,就是这个Arrays包下的ArrayList用的是构造器传进来的数组,并不像我们原来认为的ArrayList的那样会拷贝数组然后创建一个新的数组。

    这意味着我们在对这个List进行set的改动时,我们同时会更改原数组的值

    public static void main(String[] args) {
            Integer[] arr = new Integer[]{9999,88,77};
            List list = Arrays.asList(arr);
            
            list.set(1,0);
            System.out.println(list.get(1));  // 输出0
            System.out.println(arr[1]);  // 同样也输出了0
    }
    

    int[]数组

    我们都知道int是基本数据类型,如果我们向asList()方法里面传入一个int[]数组会发生什么呢?

    我们知道泛型的话需要的是对象类型,基础数据类型是不能作为泛型的。

    // 此时int[]会作为一个对象类型,然后转换为list。此时长度为1,且可以正常的取出来作为list元素
    public static void main(String[] args) {
            int[] arr = new int[]{9999,88,77};
            List<int[]> list = Arrays.asList(arr);
            System.out.println(list.size());
            System.out.println(list.get(0)[0]);
            System.out.println(list.get(0)[1]);
            System.out.println(list.get(0)[2]);
    }
    

    好了,asList()方法就学废了。一天学废一个小知识/dog


    __EOF__

  • 本文作者: captain
  • 本文链接: https://www.cnblogs.com/duizhangz/p/16660118.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    设置小于浏览器默认字体大小的显示方法
    (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
    记录一次官网访问很慢的情况
    【BurpSuite】插件开发学习之retire-js
    技术分享| 视频传输Simulcast与Svc
    ChatGPT的工作原理
    Matlab制作GUI
    集采报告丨国家药品带量采购政策及趋势分析
    java企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)
    CH1-模型训练优化
  • 原文地址:https://www.cnblogs.com/duizhangz/p/16660118.html