java.util.ArraysasList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意:

一. 如果对集合使用增加或删除元素的操作将会报错

如下代码:

List list = Arrays.asList("a","b","c");
list.add("d");

输出结果:

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at ArraysAsListTest.main(ArraysAsListTest.java:7)

Arrays.asList的源码虽然返回的是一个ArrayList,但这个ArrayListArrays内部的一个静态类(java.util.Arrays.ArrayList),并不是我们平时用的java.util.ArrayList只是名字一样,包名不一样:

这个ArrayList也继承自AbstractList,但是却没有实现add()remove()方法用这两个方法其实调用的是AbstractList的默认方法:

public void add(int index, E element) {
throw new UnsupportedOperationException();
}

直接抛出" UnsupportedOperationException"的异常!

所以当我们调用这个ArrayListadd方法时其实是调用了抽象集合类里的add方法,就抛出了上面的异常,原因是数组虽然提供了转集合的方法, 但本质上还是个数组,数组的长度是固定的,所以jdk的作者没有实现add()remove()方法。

大家在使用的时候需要注意,要结合具体业务场景判断:如果只是对转成后的集合进行遍历或使用stream()流操作都没有问题,可以正常使用(修改元素也没问题) 但如果需要新增元素或删除元素等改变集合长度的操作就要避免,否则报错就会影响到我们正常的业务逻辑。

二. 长度问题

还是ArraysasList(),该方法无法将一个基本类型的数组转换成集合List,或者说基本类型虽然能转换成功,但不是"我们想要的集合",因为asList方法接收的是一个泛型的变长参数。

而基本数据类型是无法被泛型化的,这样的话对于泛型而言,基本数据类型会被作为一个"[x"的类型,"["表示这是一个数组,"x"为当前数组的类型,例如: int[] 实际上它的类型是"[I"

这样的话Arrays.asList传入的参数是基本类型的话,会把数组当做一个元素处理(长度=1),如果我们要遍历List或获取List的长度就不准确了,类似下面的用法:

int array[] = {1,2,3,4,5};
List list = Arrays.asList(array);
System.out.println("长度="+list.size());
System.out.println("是否含有元素3="+list.contains(3));

输出结果:

长度=1
是否含有元素3=false

如果我们的代码里用到了这样获取长度或判断是否包含指定元素的操作就要注意写法,否则就会影响我们的逻辑流程!

为避免这样的问题出现,有很多种其他写法,比如将array转成包装类(即引用类型),如下:

Integer array[] = {1,2,3,4,5};
List list = Arrays.asList(array);
System.out.println("长度="+list.size());
System.out.println("是否含有元素3="+list.contains(3));

输出结果:

长度=5
是否含有元素3=true

当然也可以使用google的集合类"Ints.asList",如下:

int array[] = {1,2,3,4,5};
List list = Ints.asList(array);
System.out.println("长度="+list.size());
System.out.println("是否含有元素3="+list.contains(3));

输出结果:

长度=5
是否含有元素3=true

但是google的Ints.asList方法返回的list也是一个自己实现的集合,同样不支持addremove方法,如果既要保证转换成list后的数据长度正确又要能增删操作的话,就用java.util.ArrayList吧。

三. Arrays.asList方法返回的是数组的一个视图,也就是说对这个list的操作都会反映在原数组上

文章来源:http://javakk.com/132.html

本文由博客群发一文多发等运营工具平台 OpenWrite 发布

Java踩坑记系列之Arrays.AsList的更多相关文章

  1. java踩坑记

    1.String 相等 稍微有点经验的程序员都会用equals比较而不是用 ==,但用equals就真的安全了吗,看下面的代码 user.getName().equals("xiaoming ...

  2. mongo java 踩坑记

    为什么会有这么多坑 1.  Java会把 id:String = "合法ObjectId"  好心好意的 转为  _id:ObjectId 类型. 2. 为了避免第1点, 我定义了 ...

  3. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  4. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  5. 【踩坑记】从HybridApp到ReactNative

    前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...

  6. Spark踩坑记——共享变量

    [TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...

  7. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  8. [转]Spark 踩坑记:数据库(Hbase+Mysql)

    https://cloud.tencent.com/developer/article/1004820 Spark 踩坑记:数据库(Hbase+Mysql) 前言 在使用Spark Streaming ...

  9. Spark踩坑记——数据库(Hbase+Mysql)转

    转自:http://www.cnblogs.com/xlturing/p/spark.html 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库 ...

随机推荐

  1. 使用Azure Function玩转Serverless

    Serverless&Azure Functions 通过无服务器计算,开发者无需管理基础结构,从而可以更快构建应用程序.通过无服务器应用程序,将由云服务提供商自动预配.缩放和管理运行代码所需 ...

  2. 拉格朗日乘子法 Lagrange multipliers

  3. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.3)- 串行NOR Flash下载算法(J-Link工具篇)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是J-Link工具下i.MXRT的串行NOR Flash下载算法设计. 在i.MXRT硬件那些事系列之<在串行NOR Flash X ...

  4. 070 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 02 综合案例-数组移位-从键盘接收数据

    070 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 02 综合案例-数组移位-从键盘接收数据 本文知识点:综合案例-数组移位-从键盘接收数据 说明:因为时间紧张 ...

  5. C语言中的左移与右移 <<, >> 位运算

    这里参考了一篇很好的位运算,涉及到位运算可能会遇到的正负号问题,左右溢出怎么处理问题. 参考: 1. https://www.cnblogs.com/myblesh/articles/2431806. ...

  6. shell-的变量-全局变量

    shell变量基础及深入   1. 变量类型 变量可分为两类:环境变量(全局变量)和局部变量. 环境变量也可称为全局变量,可以在创建他们的shell及其派生出来的任意子进程shell中使用.局部变量只 ...

  7. 16.Android-activity生命周期与启动模式

    1.activity共有4个状态 如下图所示: 运行状态 如果一个活动位于屏幕的前台(可见的),那么它就是活动的或正在运行的. 暂停状态 如果一个活动失去了焦点,但仍然可见(也就是说,一个新的非全尺寸 ...

  8. 多路复用select和epoll的区别(转)

    先说下本文框架,先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法 一.问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一 ...

  9. CSS精灵图与字体图标

    CSS精灵图与字体图标 1. 精灵图 当用户访问一个网站时,需要向服务器发送请求,网页上的每张图像都要经过一次请求才能展现给用户.然而,一个网页中往往会应用很多小的背景图像作为修饰,当网页中的图像过多 ...

  10. MacBook连接蓝牙鼠标、蓝牙键盘失败的解决方案

    问题: keychron k4连接不上MacBook,但是win10和iPhone都可以成功连接. 解决方法: 1.关闭wifi: 2.连接蓝牙键盘: 3.稍等一会,再连接wifi就可以了. 另外,苹 ...