Java SE 进阶 day08

12.HashSet

1.介绍

HashSet集合底层是哈希表存储数据,哈希表是一种对于增删查改数据性能都较好的结构,在JDK8之前的,底层使用【数组+链表】组成,在JDK8开始后,底层采用【数组+链表 | 红黑树】组成.

2.HashSet保证元素唯一性
  1. 需要同时重写对象中的hashCode和equals方法

  2. hashCode和equals方法的配合流程 :

    • 当添加对象的时候, 会先调用对象的hashCode方法计算出一个应该存入的索引位置, 查看该位置上是否存在元素

      • 不存在:直接存

      • 存在:调用equals方法比较内容

        ​ false : 存

         	true : 不存
        
  3. JDK8以前 : 头插法

    JDK8以后 : 尾插法

3.HashSet扩容
  1. 底层数组扩容

    扩容数组的条件 :

    A: 当数组中的元素个数到达了 16 * 0.75 (加载因子) = 12

    扩容原数组 2 倍的大小

    B:链表挂载的元素超过了8 (阈值) 个 , 并且数组长度没有超过64

  2. 底层链表转红黑树

    链表挂载的元素超过了8 (阈值) 个, 并且数组长度到达了64

13.LinkHashSet

  1. 底层加入了双向链表.
  2. 有序、不重复、无索引。(这里的有序指的是保证存储和取出的元素顺序一致)
  3. 原理 : 底层数据结构是依然哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序。

14.Map集合

1.介绍
  1. Map集合是一种双列集合,每个元素包含两个数据。
  2. Map集合的每个元素的格式:key=value(键值对元素),Map集合也被称为“键值对集合”
2.体系集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Q6ycuzK-1692361637362)(D:\Typora\typora-user-images\Snipaste_2023-08-18_19-42-15.png)]

3.特点
  1. Map集合中底层的数据结构, 只针对键有效 !!!

  2. HashMap : 哈希表, key (键) 是唯一的

  3. LinkedHashMap : 哈希表 + 链表 , key (键) 唯一, 有序

  4. TreeMap : 红黑树, key (键) 排序

4.常用方法
方法名说明
V put (K key , V value)添加元素
V remove (Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boole containsKey(Object key)判断集合是否包含指定的键
boole containsValue(Object value)判断集合是否包含指定的值
boolea isEmpty()判断集合是否为空
int size()集合中键值对的对数
5.put 方法细节

put 方法有修改效果 —>如果键已经存在, 新值会覆盖旧值

6.Map集合的遍历
  1. 键找值的方式遍历:先获取Map集合全部的键
    再根据遍历键找值。

    //map的第一种遍历,通过键找值
        public static void main(String[] args) {
            HashMap<String ,String> hm = new HashMap<>();
            hm.put("阿芷","曲靖");
            hm.put("阿芷芷","昆明");
            hm.put("Π","云南");
    
            //迭代器遍历
            Set<String> keySet = hm.keySet();
            Iterator<String> iterator = keySet.iterator();
            while (iterator.hasNext()){
                String key = iterator.next();
                String value = hm.get(key);
                System.out.println(key+"---"+value);
            }
            System.out.println("-------------------------------------");
            //增强for循环遍历
            for (String key : hm.keySet()) {
                String value = hm.get(key);
                System.out.println(key+"---"+value);
            }
        }
    
  2. 键值对的方式遍历,把“键值对“看成一个整体

    //map的第二种遍历方式,通过键值对对象
        public static void main(String[] args) {
            HashMap<String ,String> hm = new HashMap<>();
            hm.put("阿芷","曲靖");
            hm.put("阿芷芷","昆明");
            hm.put("Π","云南");
    
            //获取所有的键值对对象
            Set<Map.Entry<String, String>> entrySet = hm.entrySet();
            //获取每一个键值对对象
            for (Map.Entry<String, String> entry : entrySet) {
                //entry.getKey()---->获取键值对对象中的键
                //entry.getValue()-->获取键值对对象中的值
                System.out.println(entry.getKey()+ "---" + entry.getValue());
            }
        }
    
  3. 通过for each遍历

     hm.forEach(new BiConsumer<String, String>() {
                @Override
                public void accept(String key, String value) {
                    System.out.println(key + "---" + value);
                }
            });
        }
    
7.Map集合的底层原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3AoKESmP-1692361637364)(D:\Typora\typora-user-images\Snipaste_2023-08-18_20-06-28.png)]

15.Collections类常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ABFiqdou-1692361637365)(D:\Typora\typora-user-images\Snipaste_2023-08-18_20-05-11.png)]

16.可变参数

  1. 介绍

    可变参数是指,参数的个数可变

  2. 本质 :

    底层是一个数组实现

  3. 注意 :

    可变参数是需要三个点,点的数量不允许改变
    不要将 … 写在类型的前面
    如果可变参数是方法中的第一个参数,后面将不允许再定义参数,因为接收不到

17.HashSet和HashMap

对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,更确切的说,HashSet中的元素,只是存放在了底层HashMap的key上, 而value使用一个static final的Object对象标识。

18.描述一下HashSet集合数据的添加过程

回答:
当我们添加元素的时候, 添加方法内部会自动调用对象的 hashCode方法, 计算出应存入的索引位置.(底层是调用了HashMap的put方式)

	- 计算方式 :
			调用hashCode方法得到原始哈希值
			对原始哈希值进行哈希扰动, 扰动的方式是向右移动16位
			使用扰动后的哈希, 和原始哈希进行 ^ 操作, 这是二次哈希操作
			然后使用运算后的哈希值, 和数组的长度进行取余操作, 计算应存入索引位置.
				- 但是源码中, 计算方式 (数组长度 - 1) & 哈希值;
				-  这样做的原因是 & 操作, 比 % 操作的效率更高.

始哈希值
对原始哈希值进行哈希扰动, 扰动的方式是向右移动16位
使用扰动后的哈希, 和原始哈希进行 ^ 操作, 这是二次哈希操作
然后使用运算后的哈希值, 和数组的长度进行取余操作, 计算应存入索引位置.
- 但是源码中, 计算方式 (数组长度 - 1) & 哈希值;
- 这样做的原因是 & 操作, 比 % 操作的效率更高.

通过阅读Java源代码,发现java的Hashset和HashMap实质上是相同的,HashSet实际上就是hashmap的value值为null 的情况,所以哈HashSet和HashMap有相同的存储元素的形式:无序不可重复。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值