1.【强制】关于 hashCode 和 equals 的处理,遵循如下规则:
1) 只要覆写 equals,就必须覆写 hashCode。
2) 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须覆写这两个方法。
3) 如果自定义对象作为 Map 的键,那么必须覆写 hashCode 和 equals。
说明:String 已覆写 hashCode 和 equals 方法,所以我们可以愉快地使用 String 对象作为 key 来使用。
解释:比特币:Collision resistance:哈希碰撞,哈希碰撞不可避免,因为输入空间远远大于输出空间。比如256位的哈希值,输出空间只有2的 256次方。根据鸽笼原理。(鸽笼原理(抽屉原理)就是"如果有五个鸽子笼,养鸽人养了6只鸽子,那么当鸽子飞回笼中后,至少有一个笼子中装有2只鸽子。")hashCode规范:在程序的一次运行中,只要没有修改equals()中用于比较的信息,x.hashCode()总是返回一致的hash值如果x.equals(y)返回true,则x和y具有相等的hash值如果x和y具有相等的hash值,x.equals(y)并不一定返回true map key要排除重复。这个问题主要和映射(Map接口)相关. 我们知道Map接口的类会使用到键(Key)的哈希码, 当我们调用put()/get()方法操作Map容器时, 都是根据Key的哈希码来计算存储位置的, 因此如果我们对哈希码的获取没有相关保证, 就可能会得不到预期的结果.eqaul方法就可以判断对象相等,但是equal方法里面判断的逻辑会很多,很复杂,说白了就是性能不够好。hashcode方法判断起来,就一行简单的代码,执行效率高,但是hashcode 有一个致命问题就是两个对象hash的时候值可能会一样。所以hashcode有时并不是都靠谱,但是如果hashcode不一样,两个对象肯定不一样。正确的对比过程应该是这样:先用hash函数对比,如果结果一样,再用equal方法对比判断两个对象是否相等;如果结果不一样,直接判定这两个对象不是同一个。
2.【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。
说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList 而是 ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。
解释:sublist重置了下标规范。Sub可以影响源集合,但源集合不影响外面。
3.【强制】使用 Map 的方法 keySet()/values()/entrySet()返回集合对象时,不可以对其进行添加元素操作,否则会抛出 UnsupportedOperationException 异常。
解释:怕程序员代码写hign了,忘了。警钟长鸣。镜像不能修改,就像不能做伪证,原来是啥就是啥。
4.【强制】Collections 类返回的对象,如:emptyList()/singletonList()等都是 immutable
list,不可对其进行添加或者删除元素的操作。
反例:如果查询无结果,返回 Collections.emptyList()空集合对象,调用方一旦进行了添加元素的操作,就会触发 UnsupportedOperationException 异常。
解释:看Collections 的emptyList源码,因为返回的是final类型。
5.【强制】在 subList 场景中,高度注意对原集合元素的增加或删除,均会导致子列表的遍历、增加、删除产生 ConcurrentModificationException 异常。
解释:父集合 1 2 3 4 5 ,sublist 刚开始用 4 5下标分布式3 4,结果父集合删掉了123,45往前挪。Sublis访问会报错。看代码collector.SubListTest.subList2
6.【强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一
致、长度为 0 的空数组。
反例:直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出
- ClassCastException 错误。