在项目中用了Arrays.asList、ArrayList的subList,被老大公开批评~

大家好,我是剽悍一小兔,独立开发者,副业搞钱尝试者,热爱技术分享。曾经当过培训机构老师,也带过大学H5编程实训课,目前还活跃在金融领域一线做全栈开发。

我会每天分享 编程技术、独立开发、思考感悟。

代表作:《JavaScript百炼成仙》

公众号:java小白翻身

如果本文能给你提供启发或帮助,欢迎动动小手指,一键三连 (点赞评论转发),给我一些支持和鼓励,谢谢。

各位程序员朋友们,今天咱们来聊聊我最近在项目里踩的两个大坑——Arrays.asList和ArrayList.subList,这俩“坑王”可把我坑惨了,被老大当众点名批评!当时我脑子一片空白,甚至怀疑自己是不是个合格的Java工程师。不过冷静下来复盘后,我发现这俩API确实暗藏玄机,今天就来给大家好好唠唠,避免大家踩同样的坑!

一、Arrays.asList:披着羊皮的狼!

先说说第一个“坑王”——Arrays.asList。那天我在项目里需要判断一批状态码,为了代码看起来清爽,我直接写了:

List<Integer> statusList = Arrays.asList(1, 2);
statusList.add(3);

结果IDE控制台直接炸出UnsupportedOperationException!我当时就懵了:这不是ArrayList吗?咋不能加元素呢?
划重点! Arrays.asList返回的根本不是我们熟悉的java.util.ArrayList,而是Arrays$ArrayList——这是Arrays的内部类,底层是固定长度的数组,只支持查询和修改,不支持增删操作

正确用法:如果需要可变集合,一定要手动转换:

List<Integer> realList = new ArrayList<>(Arrays.asList(1, 2));
realList.add(3); // 这样才对!

Arrays.asList适合干啥?做个快速初始化、判断包含关系就行,比如:

if (Arrays.asList(1, 2, 3).contains(userInput)) { ... }

别想着用它搞增删,否则就是“强行上车,后果自负”!

二、subList:表面兄弟,实则共享内存!

第二个“坑王”是ArrayList.subList。我当时需要处理书籍列表的某部分数据,写了:

List<String> bookList = new ArrayList<>(Arrays.asList("遥远的救世主", "背叛", "天幕红尘", "人生", "平凡的世界"));
List<String> luyaoBooks = bookList.subList(3, 5); // 得到["人生", "平凡的世界"]

结果一操作,直接踩中四颗“地雷”:
第一雷:改原集合,子集合跟着变!

bookList.set(3, "路遥-人生");
System.out.println(luyaoBooks); // 输出["路遥-人生", "平凡的世界"]

为啥?因为subList返回的是原集合的视图,两者共用同一个底层数组,改一个另一个必然跟着变,就像照镜子,你动镜子里的人也动!

第二雷:原集合增元素,子集合遍历爆炸!

bookList.add("早晨从中午开始");
luyaoBooks.get(0); // 抛出ConcurrentModificationException!

这不是线程问题,而是subList依赖原集合的modCount(修改次数),原集合结构一变(增/删),modCount对不上,直接炸!

第三雷:改子集合,原集合也变!

luyaoBooks.set(1, "路遥-平凡的世界");
System.out.println(bookList.get(4)); // 输出"路遥-平凡的世界"

还是视图的锅,改子集合相当于改原集合,根本没有独立性!

第四雷:子集合增元素,原集合背锅!

luyaoBooks.add("人生的枷锁");
System.out.println(bookList); // 原集合多了个元素!

结构修改在子集合做,原集合照样受牵连,谁让你们共用一个“身体”呢?

避坑指南:如果需要独立子集合,记得拷贝一份:

List<String> realSubList = new ArrayList<>(bookList.subList(3, 5));

这样两者就“断奶”了,互不影响!

三、血泪教训:别对API想当然!

这次被老大批评,我总结了三个教训:

  1. 1. Arrays.asList不是真ArrayList,名字都是骗人的,增删操作请用new ArrayList<>(...)转换!

  2. 2. subList是视图不是拷贝,改结构会互相影响,独立操作请先拷贝!

  3. 3. 别迷信IDE自动补全!List不等于ArrayList,ArrayList也分“真假”,用之前先搞清楚底层原理!

老大最后拍着我的肩膀说:“代码里没有‘看起来可以’,只有‘实际行不行’。”这句话我记牢了!多踩坑,多涨记性,这才是程序员的成长之路!

推荐阅读

程序员从幼稚到成熟的标志是什么?

写了一个mybatis-generator-ui,各种代码自动生成,开源!

程序员从幼稚到成熟的标志是什么?

为什么数据库查询要用小表驱动大表?

用vue3写了个牛马时钟,集成到小程序,已上线

写了个B站封面小偷:用Vue3+Uniapp实现一键偷图(已上线)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

剽悍一小兔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值