全是坑!慎用 Arrays.asList

Java 8 提供的 Stream 流式处理大大减少了集合类各种操作(投影、过滤、转换)的代码量,用起来非常香,所以在实际业务开发中,我们常常会把原始的数组转换为 List 类数据结构,使得其可以用上 Stream 流操作。

Arrays.asList 方法应该是各位最常用的数组一键转换为 List 的方法了,但这个方法有几个坑,如果不了解的话,排查 Bug 可能会比较困难:

  1. 坑 1:不能直接使用 Arrays.asList 来转换基本类型数组
  2. 坑 2:Arrays.asList 返回的 List 不支持增删操作
  3. 坑 3:对原始数组的修改会影响 Arras.asList 返回的那个 List

第一个坑

在如下代码中,我们初始化三个数字的 int[]数组,然后使用 Arrays.asList 把数组转换为 List:

但,这样初始化的 List 并不是我们期望的包含 3 个数字的 List,输出结果如下:

可以发现,这个 List 包含的其实是一个 int 数组,整个 List 的元素个数是 1,元素类型是整数数组

其原因是,只能是把单个 int 类型装箱为 Integer,不能把 int 数组装箱为 Integer 数组。Arrays.asList 方法传入的是一个泛型 T 类型可变参数,所以 int 数组实际上是被整体看成一个对象作为泛型类型 T:

以上,就是第一个坑:不能直接使用 Arrays.asList 来转换基本类型数组。直接遍历这样的 List 必然会出现 Bug,修复方式有两种:

  1. 最简单的,直接把数组声明为包装类型,不要用 int 这种基本类型

  2. 如果使用 Java8 以上版本可以使用 Arrays.stream 方法来转换,stream 流提供了 boxed 装箱操作:

第二个坑

把三个字符串 1、2、3 构成的字符串数组,使用 Arrays.asList 转换为 List 后,然后为 List 增加一个字符串 4:

结果如下,为 List 新增字符串 4 的操作失败了,报错  UnsupportedOperationException

第二个坑:Arrays.asList 返回的 List 不支持增删操作

因为 Arrays.asList 返回的 List 并不是我们期望的 java.util.ArrayList,而是 Arrays 的内部类 ArrayList:

ArrayList 内部类继承自 AbstractList 类,并没有覆写父类的 add 方法,而父类中 add 方法的实现,就是抛出 UnsupportedOperationException

第三个坑

把三个字符串 1、2、3 构成的字符串数组,使用 Arrays.asList 转换为 List 后,然后修改原字符串数组的第一个元素为 0:

输出如下,把原始数组的第一个元素从 1 修改为 0 后,asList 获得的 List 中的第一个元素也被修改为 0 了:

第三个坑:对原始数组的修改会影响 Arras.asList 返回的那个 List

看一下 ArrayList 的实现,可以发现 ArrayList 其实是直接使用了原始的数组。所以,我们要特别小心,把通过 Arrays.asList 获得的 List 交给其他方法处理,很容易因为共享数组,相互修改而产生 Bug。

第二个坑和第三个坑的本质原因是一样的,都是由于数组共享导致的问题,所以解决方式比较简单,重新 new 一个 ArrayList 初始化 Arrays.asList 返回的 List 即可:

修改后的代码实现了原始数组和 List 的解耦,不再相互影响。同时,因为操作的是真正的 ArrayList,add 也不再报错:



最后给大家推荐一下我的技术专栏《程序员最常见的100个问题》,最近收到的好评挺多的。

这个专栏总结了我10年工作中,遇到过的100个常见的问题。可以帮助你增加工作经验,少走很多弯路。

每篇文章会从发现问题、分析问题、解决问题、底层原理和问题总结等多个维度,从浅入深,分享了很多技术细节,以及实际的工作经验。

不光可以学到技术,而且还能知道,为什么要用某些技术,非常值得一看。

扫描下方二维码即可订阅。

原价199,今天只需12,可以永久买断,即将要涨价了。



相关推荐

  • 首屏时间,你说你优化了,那你倒是计算出给给我看啊!
  • 实力打脸!Adobe用竞品Midjourney图片训练Firefly。内部员工批评不断终爆料。用户:赚了但很惭愧,我上传了数千张
  • 企业级离线数仓分层设计和演化之路
  • 面试官:说一下加密后的数据如何进行模糊查询?
  • 面试官:线上MySQL的自增id用尽怎么办?
  • 字节员工:最近金价好高。家里还有一斤多黄金,要不要出一波呀
  • GPT-4升级被曝引入Q*,推理/数学更强废话更少,竞技场重夺王位
  • 手机可以跑大模型了,一夜下载量超2000
  • [开源]一款通用管理平台,模块插件式开发,前后端分离,开箱即用
  • KDD Cup 2024:Meta LLMs RAG挑战赛
  • 今日代码大赏 | Java 实现二分查找算法
  • 三轮电商公司面试,已拿 Offer!
  • 一个小公司的技术开发心酸事(已倒闭)
  • 高校老师因发消息爱打问号被学生投诉!被学校撤职后反手上诉获赔13万
  • 来势汹汹的Linux系统激爆网络神秘地带
  • 重磅发布:aiXcoder-7B代码大模型正式开源
  • 开源副屏「操作系统」底层采用Electron,是生产力工具还是美丽的废物?
  • 基于OpenCV的路面质量检测
  • 判定二级教学事故!大学教师被解聘
  • 【深度学习】Unet++(pytorch实现)