Java基础之Array.asList的使用,将数组转成List,全是坑

上一篇提及到Arrays的一些常用方法,其中Arrays.asList还是要单独说一下,因为里面的坑太大了,用的时候才发现远远没有想像的那么简单。
坑一、使用集合的修改方法:add()、remove()、clear()会抛出异常
转换的list只可用来做读取操作,想要修改是不行的。值得注意的是,asList方法只适合转换成List之后进行读取的基本操作,虽然转成List集合了,但是底层依然是数组,一不小心就会出现大问题,还是要慎用,坑还是比较大的。Arrays.asList() 方法返回的并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法。
阿里巴巴Java手册对其表述如下:
在这里插入图片描述
坑二、传递的数组必须是对象数组,而不是基本类型
Arrays.asList()是泛型方法,传入的对象必须是对象数组。比如你创建了一个int数组,想要转成list,调用Array.asList不会报错,但是得到的不是你想要的,举个例子

int[] myArray = { 1, 2, 3 };
List myList = Arrays.asList(myArray);
System.out.println(myList.size());
System.out.println(myList.get(0));

运行结果

1
[I@1540e19d

神不神奇,size大小居然是1,打印的get(0)居然是一个地址(就是数组myArray的地址),为什么会这样,因为当传入一个原生数据类型(int,long,double,float…)数组时,Arrays.asList() 的真正得到的参数就不是数组中的元素,而是数组对象本身!直接把数组当成一个对象进行转化,此时List 的唯一元素就是这个数组,这也就解释了上面的代码。myArray被看作了一个对像。如果把int[] myArray = { 1, 2, 3 };改为Integer[] myArray = { 1, 2, 3 };就没问题了。

Integer[] myArray = { 1, 2, 3 };
List myList = Arrays.asList(myArray);
System.out.println(myList.size());
System.out.println(myList.get(0));
//输出:
3
1

坑三、正确转为ArrayList的方法

  1. 手动写,学的过程就是敲代码的过程,学习的时候多敲代码没有坏处

  2. 最简单的方法 List list = new ArrayList<>(Arrays.asList("a", "b", "c"))

  3. 使用 Java8 的Stream(推荐)

    Integer [] myArray = { 1, 2, 3 };
    List myList = Arrays.stream(myArray).collect(Collectors.toList());
    //基本类型也可以实现转换(依赖boxed的装箱操作)
    int [] myArray2 = { 1, 2, 3 };
    List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());
    

其实还有别的方法,自行百度。
List 转 数组直接调用list.toArray()就好了,返回是一个Object[],想改为String的话加参数new String[size];就可以了,随jvm优化,这里的size是0就可以,因为只是为了声明其返回类型。

坑四、不要在for循环里尝试删除ArrayList里的元素
如果要进行remove操作,可以调用迭代器的 remove 方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove/add方法,迭代器都将抛出一个ConcurrentModificationException,这就是单线程状态下产生的 fail-fast 机制。

fail-fast 机制:多个线程对 fail-fast 集合进行修改的时,可能会抛出ConcurrentModificationException,单线程下也会出现这种情况,上面已经提到过。

阿里巴巴开发手册对其解释
在这里插入图片描述
回答一下上面的提问。

List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
for (String s : list) {
     if ("2".equals(s)){
         list.remove(s);
     }
}
System.out.println(list);

当为1的时候正常运行,换成2的运行结果如下,可以看到ConcurrentModificationException异常出现

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at test.com.A.main(A.java:37)

参考:Java疑难点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值