java第16天 hashSet以及linkedHashSet

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