Arrays.asList()使用中遇到的问题


title: Arrays.asList()使用中遇到的问题
date: 2020-04-17 14:08:37
categories:java
tags:

概述

Arrays是java.util包中提供的工具类,主要用于对数组进行各种操作

Arrays.asList()是该类中提供的一个静态方法,根据源码注释,作用为基于特定数组返回一个固定大小的列表

Returns a fixed-size list backed by the specified array

问题

运行如下代码时出现异常:

String[] strs={"str1","str2","str3","str4"};

List<String> arr=Arrays.asList(strs);
        
arr.add("str5");//抛出异常java.lang.UnsupportedOperationException
arr.remove("str1");//抛出异常java.lang.UnsupportedOperationException

System.out.println(arr);

这里通过Arrays.asList()将String数组转化为List,但对List进行add和remove操作时却报异常UnsupportedOperationException,这是为啥呢,为什么操作不支持呢?

根据上述概述,该方法返回一个fixed-size,即大小不能改变的列表,该方法的源码很简单,

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

由源码可知,该方法返回一个ArrayList,那为啥ArrayList就不支持add和remove操作了呢?

原来,这里的ArrayList并不是java.util包中的集合类ArrayList,而是在Arrays类中自定义的一个内部类,其类的定义源码就在asList()方法源码下;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SlsXF0hb-1589178740353)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420144009.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8x6YuRxF-1589178740354)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420144148.png)]

(话说为啥不换个名)

该内部类源码为

private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
    //内部源码省略
    ....
    ....
    }

可以看到该类继承了AbstractList类,并实现了RandomAccessSerializable接口;该类源码中没有定义add,remove方法

进一步查看AbstractList类源码

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    //部分源码省略
    ...
    ...
    
 	public boolean add(E e) {
        add(size(), e);
        return true;
    }
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }
     public E remove(int index) {
        throw new UnsupportedOperationException();
    }
    
    //部分源码省略
    ...
    ...
}

可以看到,该类继承AbstraceCollection类并实现List接口,执行add,remove操作时均抛出UnsupportedOperationException异常;

事实上,查看AbstraceList类其余源码可以看到,其中set方法也抛出UnsupportedOperationException异常,但ArrayList内部类重写了set方法,所以可以执行set操作

注意:
  1. 执行set操作时,如下代码,分别对数组和由数组转化的List集合元素进行修改
 public static void main(String[] args) {
     String[] strs={"str1","str2","str3","str4"};
     List<String> list=Arrays.asList(strs);
     
     System.out.println(Arrays.toString(strs));
     System.out.println(list);
     
     strs[0]="str1_new";//对strs进行修改
     list.set(1,"str2_new");//对list进行修改
     
     System.out.println(Arrays.toString(strs));
     System.out.println(list);
 }

结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sSor2LLL-1589178740356)(https://gitee.com/yanzixian/picBed/raw/master/img202004/20200420151851.png)]

发现对数组进行的修改影响到了集合,对于集合进行的修改也影响到了数组;

这是因为asList()转化得到的集合元素直接引用了数组,数组和集合的变化会同步,这同时可能会导致一些编码上的问题

  1. asList()方法不可操作基本数据类型;因为由于通过new创建一个Arrays.ArrayList时,其参数为可变长泛型,而基本类型是无法泛型化的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值