HashSet
基本用法
底层
构造方法
HashSet1 基本用法
1 创建对象
HashSet<泛型> set = new HashSet<>();
// HashSet唯一 去重
HashSet<泛型> set = new HashSet<>(Collection);
2 一次添加一个
set.add(元素);
3 一次添加多个
Collections.addAll(set,泛型 ... x);
4 清空
set.clear();
5 判断是否为空
set.isEmpty();
6 集合大小
set.size();
7.遍历
第一种 foreach
第二种 迭代器
HashSet2-唯一
唯一:内存中的同一个对象 不能添加多次
"唯一":内存中不是同一个对象 但是通过覆盖方法视为同一个对象 也不能添加多次(程序员眼中)
HashSet3-添加
HashSet4 - 底层
add(元素) 底层尊重 hashCode == equals
contains(元素) 底层尊重 hashCode == equals
remove(元素) 底层尊重 hashCode == equals
HashSet4Plus - CME
CME ConcurrentModificationException 并发修改异常
CME可能出现的场景:
使用迭代器遍历的过程中 直接操作集合的大小 set.remove(xx) set.add(xx) 可能产生CME
解决方案:
1 迭代器遍历 + 迭代器的删除 【删除=》CME】
2 新的集合暂存 出了遍历之后 再加回原来的集合【添加=》CME】
底层原理:
每一个集合创建的时候
底层一个变量modCount记录对集合的操作次数[添加/删除/涉及修改大小的操作]
每次修改集合的大小都会导致 modCount++
当获取迭代器对象的时候 迭代器会将modCount的数值
拷贝到自己的变量中 expectedModCount
每次 car.next() 会判断modCount和expectedModCount是否相等
如果二者不相等 就会出现 CME
HashSet5 - 修改
不要轻易修改参与哈希码值生成的属性
如果要修改参与哈希码值的属性 1删2改3添加
如果要修改没有参与哈希码值的属性 直接修改
HashSet6 - HashSet的构造方法
HashSet set = new HashSet(); // 分组组数16 加载因子0.75
HashSet set = new HashSet(COllection); // 去重
HashSet set = new HashSet(int 分组组数); // 加载因子0.75【分组组数变2的n次方】
HashSet set = new HashSet(int 分组组数, float加载因子);
HashSet7 - HashSet的并交补
并集 addAll 交集 retainAll 差集 removeAll
// addAll 并集 / retainAll 交集 / removeAll 差集
// => 不可逆 【直接修改原本调用者集合】
// 需不需要备份?
public static void main(String[] args){
HashSet<String> zs = new HashSet<>();
Collections.addAll(zs, "语文","数学","英语");
HashSet<String> lisi = new HashSet<>();
Collections.addAll(lisi, "物理","数学","英语");
1 zs和lisi一共选修哪些课程? 语文数学英语物理
并集 addAll
备份:HashSet<String> temp = new HashSet<>(zs);
temp.addAll(lisi);
System.out.println(temp);
2 zs和lisi都选的课程是哪些?数学 英语
交集 retainAll
zs.retainAll(lisi);
System.out.println(zs);
3 zs选修但是lisi没有选修课程是那些?语文
差集 removeAll
zs.removeAll(lisi);
System.out.println(zs);
}
面试题:相等对象与哈希码值
如果两个对象视为相等对象 两个对象哈希码值必须一样√
* 如果两个对象的哈希码值不一样 肯定不是"同一个"对象 √
* 如果两个对象不是"同一个"对象
/哈希码值肯定不一样 X [重码]
LinkedHashSet
LinkedHashSet => 有序-添加[没有下标] 唯一
哈希表+链表【记录下一个元素的位置】
LinkedHashSet<Integer> set = new LinkedHashSet<>();
Collections.addAll(set,98,67,12,45);
System.out.println(set);// 98 67 12 45