- 【强制】在 subList 场景中,高度注意对父集合元素的增加或删除,均会导致子列表的遍历、增加、删
除产生 ConcurrentModificationException 异常。
说明:抽查表明,90% 的程序员对此知识点都有错误的认知。 - 14.【强制】不要在 foreach 循环里进行元素的 remove / add 操作。remove 元素请使用 iterator 方式,
如果并发操作,需要对 iterator 对象加锁。
正例:List list = new ArrayList<>();
list.add(“1”);
list.add(“2”);
Iterator iterator = list.iterator();
while (iterator.hasNext()) { String item = iterator.next();
if (删除元素的条件) {
iterator.remove();
}
Java 开发手册(黄山版)
13/51 }
反例:
for (String item : list) {
if (“1”.equals(item)) {
list.remove(item);
} }
说明:反例中的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”会是同样的结果吗? - 9.【强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为
0 的空数组。 - 10.【强制】使用 Collection 接口任何实现类的 addAll() 方法时,要对输入的集合参数进行 NPE 判断。
说明:在 ArrayList#addAll 方法的第一行代码即 Object[] a = c.toArray();其中 c 为输入集合参数,如果为 null,
则直接抛出异常。 - 5.【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异常:
java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。
说明:subList() 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList 本身,而是 ArrayList 的一个视图,对于
SubList 的所有操作最终会反映到原列表上。 - 6.【强制】使用 Map 的方法 keySet() / values() / entrySet() 返回集合对象时,不可以对其进行添加元素
操作,否则会抛出 UnsupportedOperationException 异常。 - 8.【强制】在 subList 场景中,高度注意对父集合元素的增加或删除,均会导致子列表的遍历、增加、删
除产生 ConcurrentModificationException 异常。
说明:抽查表明,90% 的程序员对此知识点都有错误的认知。 - 使用工具类 Arrays.asList() 把数组转换成集合时,不能使用其修改集合相关的方法,它的 add
/ remove / clear 方法会抛出 UnsupportedOperationException 异常。
说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList 体现的是适配器模式,只
是转换接口,后台的数据仍是数组。
String[] str = new String[]{ "yang", "guan", "bao" };
List list = Arrays.asList(str);
第一种情况:list.add(“yangguanbao”); 运行时异常。
第二种情况:str[0] = “change”; list 中的元素也会随之修改,反之亦然。
19.【推荐】高度注意 Map 类集合 K / V 能不能存储 null 值的情况,如下表格:
集合类 Key Value Super 说明
Hashtable 不允许为 null 不允许为 null Dictionary 线程安全
Java 开发手册(黄山版)
14/51
TreeMap 不允许为 null 允许为 null AbstractMap 线程不安全
ConcurrentHashMap 不允许为 null 不允许为 null AbstractMap 锁分段技术(JDK8:CAS)
HashMap 允许为 null 允许为 null AbstractMap 线程不安全
反例:由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 null 值,而事实上,存储 null 值时会抛
出 NPE 异常。