Arrays.asList()你真的知道怎么用吗?
2024-09-07 03:37:51
发现问题
前几天在看别人的项目的时候,发现一个问题,简单复现一下这个问题
// 注意这是一个Integer对象的数组哦
Integer[] arr = new Integer[]{9999,88,77};
List<Integer> list = Arrays.asList(arr);
// 执行以下操作,有问题么?
list.add(1);
list.remove(0);
好的,如果你觉得没错,和我刚开始的想法一致。在我没有认真学习这个asList方法时,天真的以为没有问题,顾名思义啊,就是把数组转换成List呗。
// 恭喜,喜提报错,如果是这样测试该找你麻烦了,/(ㄒoㄒ)/~~
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at TestForAsList.main(TestForAsList.java:13)
废话不多说,我们直接进源码里面看看。
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a); // 看起来没有任何异常,emm。然而呢,这个ArrayList并不是Java.util包下的ArrayList,而是一个在Arrays下实现的内部类。
}
我们发现这个静态内部类里面并没有实现List的add和remove方法。那么子类将延用父类AbstractList的方法实现,这个继承应没有什么问题。
// 我们进入这个父类的实现,发现了报错的根源。。
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
}
总结:
究其原因,就是这个asList方法返回的是一个内部类,只实现了一些遍历以及更新的方法。下次使用它的时候需要注意一下。
扩展知识点
数组值的变化
然后我就发现了这个很有意思的点,就是这个Arrays包下的ArrayList用的是构造器传进来的数组,并不像我们原来认为的ArrayList的那样会拷贝数组然后创建一个新的数组。
这意味着我们在对这个List进行set的改动时,我们同时会更改原数组的值。
public static void main(String[] args) {
Integer[] arr = new Integer[]{9999,88,77};
List<Integer> list = Arrays.asList(arr);
list.set(1,0);
System.out.println(list.get(1)); // 输出0
System.out.println(arr[1]); // 同样也输出了0
}
int[]数组
我们都知道int是基本数据类型,如果我们向asList()方法里面传入一个int[]数组会发生什么呢?
我们知道泛型的话需要的是对象类型,基础数据类型是不能作为泛型的。
// 此时int[]会作为一个对象类型,然后转换为list。此时长度为1,且可以正常的取出来作为list元素
public static void main(String[] args) {
int[] arr = new int[]{9999,88,77};
List<int[]> list = Arrays.asList(arr);
System.out.println(list.size());
System.out.println(list.get(0)[0]);
System.out.println(list.get(0)[1]);
System.out.println(list.get(0)[2]);
}
好了,asList()方法就学废了。一天学废一个小知识/dog
最新文章
- 【译】Core Java Questions and Answers【1-33】
- IOS开发之显示微博表情
- linux修改mysql密码
- leetcode 205
- VBA使用的Randomize和DoEvents
- Google类VR设备知识
- Button 设置适应不同版本 旋转以后大小相应的改变
- UIButton之Block回调
- 结构体定义 typedef struct 用法详解和用法小结
- Java Access Levels(访问控制)
- IOC容器在框架中的应用
- Python网络爬虫
- 关于Unity项目中创建项目遇到的一些问题
- 基于Spring的RPC通讯模型.
- Spring Boot 2.x :通过 spring-boot-starter-hbase 集成 HBase
- 自己写的JdbcUtils小工具-----得到Connection对象
- 洛谷 4383 [八省联考2018]林克卡特树lct——树形DP+带权二分
- js日期操作,某天的N天后,一个月后的日期
- 使用GitHub和Eclipse进行javaEE开发步骤
- Angular面试题三
热门文章
- SAP 实例 9 Text output
- java+mybatis实现一个简单的银行系统,实现存取款与账户查询
- tail -f 、tail -F、tailf的区别
- golang的超时处理使用技巧
- Unity3D学习笔记6——GPU实例化(1)
- Linux从root切换某个用户时可能出现:-bash-4.1$
- 【跟着大佬学JavaScript】之节流
- java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
- 匿名对象和private关键字
- BACnet MS/TP转MQTT网关金鸽BL103