Java踩坑记录之Arrays.AsList

前言

java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化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,但这个ArrayList是Arrays内部的一个静态类(java.util.Arrays.ArrayList),并不是我们平时用的java.util.ArrayList只是名字一样,包名不一样:

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

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

直接抛出" UnsupportedOperationException"的异常!

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

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

二. 长度问题

还是Arrays的asList(),该方法无法将一个基本类型的数组转换成集合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也是一个自己实现的集合,同样不支持add和remove方法,如果既要保证转换成list后的数据长度正确又要能增删操作的话,就用java.util.ArrayList吧。

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

总结

到此这篇关于Java踩坑记录之Arrays.AsList的文章就介绍到这了,更多相关Java踩坑Arrays.AsList内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java 源码分析Arrays.asList方法详解

    最近,抽空把java Arrays 工具类的asList 方法做了源码分析,在网上整理了相关资料,记录下来,希望也能帮助读者! Arrays工具类提供了一个方法asList, 使用该方法可以将一个变长参数或者数组转换成List . 其源代码如下: /** * Returns a fixed-size list backed by the specified array. (Changes to * the returned list "write through" to the arr

  • Java Arrays.asList使用方法解析

    Arrays.asList()方法的作用是将数组或一些元素转为集合,而你得到的集合并不是我们通常使用的List集合,而是Arrays里面的一个内部类.阿里的开发手册上java开发规范说到使用工具类Arrays.asList()方法把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出java.lang.UnsupportedOperationException的异常. 一.Arrays.asList的方法说明 public static void mai

  • Java用Arrays.asList初始化ArrayList实例方法

    Java中使用Arrays.asList初始化ArrayList package xiaoling; import java.util.Arrays; import java.util.ArrayList; import java.util.List; public class ListTest{ public static void main(String[] args){ List<List<Integer>> list = new ArrayList<>(); f

  • Java中Arrays.asList()方法详解及实例

    Arrays.asList() 是将数组作为列表. 问题来源于: public class Test { public static void main(String[] args) { int[] a = {1, 2, 3, 4}; List list = Arrays.asList(a); System.out.println(list.size()); //1 } } 期望的输出是 list 里面也有4个元素,也就是 size 为4,然而结果是1. 原因如下: 在 Arrays.asLis

  • Java踩坑记录之Arrays.AsList

    前言 java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意: 一. 如果对集合使用增加或删除元素的操作将会报错 如下代码: List list = Arrays.asList("a","b","c"); list.add("d"); 输出结果: Exception in thread &q

  • Java踩坑记录之BigDecimal类

    前言 在java.math包中提供了对大数字的操作类,用于进行高精确计算,如BigInteger,BigDecimal类.而平常我们开发中使用最多的float和double只能适用于一般的科学和工程计算,如果要在比较精确的计算方面如货币,那么使用float和double会相应的丢失精度,因此用于精密计算大数字的类BigDecimal就必不可少了.所以BigDecimal适合商业计算场景,用来对超过16位有效位的数进行精确的运算.但是BigDecimal的使用并不像float和double那样,使

  • Java常见踩坑记录之异常处理

    目录 一.Java异常类层次结构 二.Throwable类常用方法 三.try-catch-finally 四.使用 try-with-resources 来代替try-catch-finally 五.自定义异常 总结 一.Java异常类层次结构 Java中,所有的异常都来源于java.lang包中的Throwable类,它有两个重要的子类,Exception(异常)和Error(错误). Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获.Exception 又可以

  • Java中Objects.equals踩坑记录

    目录 前言 1. 案发现场 2. 判断相等的方法 2.1 使用==号 2.2 使用equals方法 3. 空指针异常 4. Objects.equals的作用 5. Objects.equals的坑 总结 前言 最近review别人代码的时候,发现有个同事,在某个业务场景下,使用Objects.equals方法判断两个值相等时,返回了跟预期不一致的结果,引起了我的兴趣. 原本以为判断结果会返回true的,但实际上返回了false. 记得很早之前,我使用Objects.equals方法也踩过类似的

  • SpringMVC中文乱码踩坑记录

    目录 问题 问题根源 解决方案 方案一 方案二 问题 使用SpringMVC在返回一个字符串时发生了中文乱码问题.produces属性无效 @RequestMapping(value = "/nihao", produces = "text/plain;charset=UTF-8") @ResponseBody public String hello(HttpServletResponse response) throws UnsupportedEncodingEx

  • JavaWeb踩坑记录之项目访问不到html文件

    踩坑问题和原因 踩坑问题 由于博主的JavaWeb是速成所以对一些知识点掌握的不是很熟,所以也就出现了今天这个问题——Tomcat访问不到html文件. 在运行是总是会出现404.每次出现这个就很烦,让人摸不着头脑.虽然这个问题其实对一些项目没有很大的影响,但是他会让我的项目目录会很杂乱.总的来说该问题就是不解决它,就会出现一堆静态资源都在一个文件夹.这可能会导致后期找一些项目的文件就得找半天. 踩坑原因 由于粗心的我把一些html文件都放在WEB-INF下面.因为WEB-INF下的资源不能直接

  • Spring Data JPA踩坑记录(@id @GeneratedValue)

    目录 Spring Data JPA踩坑记录 JPA踩坑:No property xxx found for type xxx 问题发现 问题解决 Spring Data JPA踩坑记录 最近在做自己的一个项目时 使用了spring jpa 由于数据库用的是mysql 在给实体类entity 的id给注解时@Id遇到了一个坑 自己找了许久才在stackoverflow 上找到了答案 注意 再查询数据库的时候并不会因此报错 而当你的主键是自增的时候 在添加数据的时候就会报错了 看看我们的实体类 注

  • .net core 3.1在iis上发布的踩坑记录

    前言 写这篇文章的目的是希望像我一样喜欢.net 的人在发布 core到 iis上时少走点弯路 网上找了些资料,其实实际操作比较简单,就是有几个坑很恶心 踩坑记录 首先是你的服务器需要有core 的运行环境,安装前先关闭iis dotnet-hosting-3.1.4-win.exe 可以去微软的官网找最新的版本(去微软的官网找你要的版本就好了) 安装成功后,第一个坑出现了,启动iis,发现原来在iis上的网站都报503错误了. 直接玩大了,最后发现就是这个东西搞的鬼,你卸载它iis之前的网站就

  • Linux/Docker 中使用 System.Drawing.Common 踩坑记录分享

    前言 在项目迁移到 .net core 上面后,我们可以使用 System.Drawing.Common 组件来操作 Image,Bitmap 类型,实现生成验证码.二维码,图片操作等功能.System.Drawing.Common 组件它是依赖于 GDI+ 的,然后在 Linux 上并没有 GDI+,面向谷歌编程之后发现,Mono 团队使用 C语言 实现了GDI+ 接口,提供对非Windows系统的 GDI+ 接口访问能力,这个应该就是libgdiplus.所以想让代码在 linux 上稳定运

  • 关于python scrapy中添加cookie踩坑记录

    问题发现: 前段时间项目中,为了防止被封号(提供的可用账号太少),对于能不登录就可以抓取的内容采用不带cookie的策略,只有必要的内容才带上cookie去访问. 本来想着很简单:在每个抛出来的Request的meta中带上一个标志位,通过在CookieMiddleware中查看这个标志位,决定是否是给这个Request是否装上Cookie. 实现的代码大致如下: class CookieMiddleware(object): """ 每次请求都随机从账号池中选择一个账号去访

随机推荐