使用List需要注意的点
1. 概述
在使用List集合时有些地方需要注意一下的, 不然会出现一些莫名其妙的错误.
2. Arrays.asList();
2-1. 产生不可操作的集合
来看一个例子.
Integer[] array = {1, 2, 3, 4, 5};
List<Integer> list = Arrays.asList(array);
list.remove(1);
会直接抛出java.lang.UnsupportedOperationException异常, 为什么呢?
答案是: 返回的List非java.util.ArrayList. 而是在Arrays类内部有一个静态内部类叫ArrayList.
静态内部类ArrayList并没有提供所有的方法实现, 有些方法在抽象类中仅仅是一个抛异常的实现, 上述的remove就是这种情况. asList返回的列表只不过是披着list的外衣, 它并没有list的基本特性(变长), 该list是一个长度不可变的列表, 传入参数的数组有多长, 其返回的列表就只能是多长. 所以不要试图改变asList的返回列表.
Arrays.asList的代码如下:
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
// 省略部分源码
}
该类也是继承了AbstractkList抽象类, 只是该类并没有提供所有方法的实现.
2-2. 需要传入对象数组而不是基本类型数组
看个例子:
int[] array1 = {1, 2, 3, 4, 5};
List<int[]> list1 = Arrays.asList(array1);
System.out.println(list1.size()); // 1
Integer[] array2 = {1, 2, 3, 4, 5};
List<Integer> list2 = Arrays.asList(array2);
System.out.println(list2.size()); // 5
看到Array.asList的返回值的泛型就明白, list1中存储的实际是一个数组. 为什么这样呢? 数值类型不能被泛型化, 比如List<int>
是不对的, 必须是List<Integer>
才对.
3. arrayList.subList();
3-1. subList返回的并不是ArrayList
方法返回的是一个内部类SubList, 并不是ArrayList, SubList也是继承AbstractList, 内部引用了原列表的List.
3-2. subList返回的仅仅是一个视图
subList返回的仅仅是一个视图, 对subList返回值的所有操作都会作用在原列表中.
看一个例子
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
List<String> subList = list.subList(2, 4);
subList.add("F");
System.out.println(list); // 输出 [A, B, C, D, F, E]
通过输出结果可知, F被添加到原列表中了.
3-3. 生成子列表时, 不要试图去操作原列表
因为子列表是根据原列表动态生成的, 所以如果原列表变了, 那么操作子列表时就会发生ConcurrentModificationException异常. 这个异常的原因相信你也知道, 就是modCount改变了导致的.
3-4. 推荐使用subList处理局部链表
比如, 有一个需求要删除列表100-200位置处的数据, 通常我们这样写:
int start = 100;
int end = 200;
for (int i = start; i <= end; i++) {
list.remove(start);
}
通过subList, 我们有一个更简洁的处理方式:
list.subList(100, 200).clear();
简洁.
不定期更新
可能还会遇到集合相关的坑.
随机推荐
- jQuery-1.样式篇
jQuery对象与DOM对象 对于才开始接触jQuery库的初学者,我们需要清楚认识一点: jQuery对象与DOM对象是不一样的 可能一时半会分不清楚哪些是jQuery对象,哪些是DOM对象,下面重 ...
- 用CSS3制作尖角标签按钮样式
如图的效果.标签有背景色,且左侧有一个三角形,三角形中间有个白色的圆圈. 你一定在想这个效果是背景图切出来的吧——答案是没有用到任何图片 那你会不会在想这个效果的html结构很复杂呢——答案是最简单的 ...
- Python语法教程总结规范
Python语法易错点记录 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...
- 几个特殊的IP地址
1)私有地址 IP地址在全世界范围内唯一,看到这句话你可能有这样的疑问,像192.168.0.1这样的地址在许多地方都能看到,并不唯一,这是为何?Internet管理委员会规定如下地址段为私有 ...
- Oracle使用笔记(二)
一.表空间 1.创建表空间 create tablespace db_test --表空间名 datafile 'D:\oracle\product\11.2.0\dbhome_1\oradata\o ...
- RESTful Loads
RESTful 一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制. 概述 ...
- 阿里java开发规范 强制约束
http://news.51cto.com/art/201901/591018.htm :阿里开发强制要求的11条索引创建规范,提高性能 https://blog.csdn.net/Lujunwei ...
- js 功能
---IE wps excelApp =ActiveXObject("Excel.Application") App.DisplayAlerts = false 不显示警告 App ...
- Actifio CDS 2TB MDisk limits
**** updated 7 Aug 2016 - reformatted and corrected out of date info *** Background Depending on you ...
- NumPy 基础用法
NumPy 是高性能科学计算和数据分析的基础包. 它是 pandas 等其他各种工具的基础. 主要功能: ndarray 一个多维数组结构, 高效且节省空间 无需循环对整组数据进行快速运算的数学函数 ...