集合处理
1. 【强制】关于hashCode和equals的处理,遵循如下规则: 只要覆写 equals,就必须覆写 hashCode。 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进⾏判断,所以 Set 存储的对象必须覆写 这两种⽅法。 如果⾃定义对象作为 Map 的键,那么必须覆写 hashCode 和 equals。 说明:String 因为覆写了 hashCode 和 equals ⽅法,所以可以愉快地将 String 对象作为 key 来使⽤。
2. 【强制】判断所有集合内部的元素是否为空,使⽤isEmpty()⽅法,⽽不是 size()==0的⽅式。 说明:在某些集合中,前者的时间复杂度为 O(1),⽽且可读性更好。
3. 【强制】在使⽤java.util.stream.Collectors类的toMap()⽅法转为Map集合时, ⼀定要使⽤含有参数类型为 BinaryOperator,参数名为 mergeFunction 的⽅ 法,否则当出现相同 key值时会抛出 IllegalStateException 异常。 说明:参数 mergeFunction 的作⽤是当出现 key 重复时,⾃定义对 value 的处 理策略。
正例:
List> pairArrayList = new ArrayList<>(3);
pairArrayList.add(new Pair<>("version", 12.10));
pairArrayList.add(new Pair<>("version", 12.19));
pairArrayList.add(new Pair<>("version", 6.28));
Map map = pairArrayList.stream().collect(
// ⽣成的 map 集合中只有⼀个键值对:{version=6.28}
Collectors.toMap(Pair::getKey, Pair::getValue, (v1, v2) -> v2));
反例:
String[] departments = new String[] {"iERP", "iERP", "EIBU"};
// 抛出 IllegalStateException 异常
Map map = Arrays.stream(departments) .collect(Collectors.toMap(String::hashCode, str -> str));
4. 【强制】在使⽤java.util.stream.Collectors类的toMap()⽅法转为Map集合时, ⼀定要注意当 value 为 null 时会抛 NPE 异常。
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 异常。
7. 【强制】Collections 类返回的对象,如:emptyList()/singletonList()等都是 immutable list,不可对其进⾏添加或者删除元素的操作。
8. 【强制】在subList场景中,⾼度注意对⽗集合元素的增加或删除,均会致⼦列 表的遍历、增加、删除产⽣ ConcurrentModificationException 异常。
9. 【强制】使⽤集合转数组的⽅法,必须使⽤集合的 toArray(T[] array),传⼊的 是类型完全⼀致、⻓度为 0 的空数组。
10. 【强制】不要在 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();
} }
反例:
for (String item : list) { if ("1".equals(item)) { list.remove(item); } }
说明:以上代码的执⾏结果肯定会出乎⼤家的意料,那么试⼀下把“1”换成“2”, 会是同样的结果吗?
11. 【推荐】⾼度注意 Map 类集合 K/V 能不能存储 null 值的情况,如下表格: 集合类 Key允许 为null Value允许 为null Super 说明 Hashtable 否 否 Dictiona ry 线程安全 ConcurrentHa shMap 否 否 Abstract Map 锁分段技术(JDK 8:CAS) TreeMap 否 是 Abstract Map 线程不安全 HashMap 是 是 Abstract Map 线程不安全