java-集合-HashMap(详解)

HashMap集合:

一、HashMap集合总结:

1、HashMap集合底层是哈希表/散列表的数据结构。

2、哈希表是一个怎样的数据结构呢?
哈希表是一个数组和单向链表的结合体。
数组:在查询方面效率很高,随机增删方面效率很低。
单向链表:在随机增删方面效率较高,在查询方面效率很低。
哈希表将以上的两种数据结构融合在一起,充分发挥它们各自的优点。

3、HashMap集合底层的源代码:

 public class HashMap{
       // HashMap底层实际上就是一个数组。(一维数组)
       Node<K,V>[] table;
       // 静态的内部类HashMap.Node
       static class Node<K,V> {
           final int hash; 
           /*
           哈希值(哈希值是key的hashCode()方法的执行结果。
           hash值通过哈希函数/算法,可以转换存储成数组的下标。)
           /*
           final K key; // 存储到Map集合中的那个key
           V value; // 存储到Map集合中的那个value
           Node<K,V> next; // 下一个节点的内存地址。
       }
   }

哈希表/散列表:一维数组,这个数组中每一个元素是一个单向链表。(数组和链表的结合体。)

4、最主要掌握的是:
map.put(k,v)
v = map.get(k)
以上这两个方法的实现原理,是必须掌握的。
5、HashMap集合的key部分特点:
无序,不可重复。
为什么无序? 因为不一定挂到哪个单向链表上。
不可重复是怎么保证的? equals方法来保证HashMap集合的key不可重复。
如果key重复了,value会覆盖。

  放在HashMap集合key部分的元素其实就是放到HashSet集合中了。
  所以HashSet集合中的元素也需要同时重写hashCode()+equals()方法。

6、哈希表HashMap使用不当时无法发挥性能!
假设将所有的hashCode()方法返回值固定为某个值,那么会导致底层哈希表变成了纯单向链表。
这种情况我们成为:散列分布不均匀。
什么是散列分布均匀?
假设有100个元素,10个单向链表,那么每个单向链表上有10个节点,这是最好的,是散列分布均匀的。
假设将所有的hashCode()方法返回值都设定为不一样的值,可以吗,有什么问题?
不行,因为这样的话导致底层哈希表就成为一维数组了,没有链表的概念了,
也是散列分布不均匀。
散列分布均匀需要你重写hashCode()方法时有一定的技巧。

7、重点:放在HashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同时重写hashCode和equals方法。

8、HashMap集合的默认初始化容量是16,默认加载因子是0.75
这个默认加载因子是当HashMap集合底层数组的容量达到75%的时候,数组开始扩容。

重点,记住:HashMap集合初始化容量必须是2的倍数,这也是官方推荐的,这是因为达到散列均匀,为了提高HashMap集合的存取效率,所必须的。

二、遍历Map集合:
    Map<Integer,String> map = new HashMap();
    map.put(1, "zhangsan");
    map.put(2, "lisi");
    map.put(3, "wangwu");
    map.put(4, "zhaoliu");
    map.put(1, "king"); //key重复的时候value会自动覆盖。
    System.out.println(map.size()); // 4
    
    // 遍历Map集合
    Set<Map.Entry<Integer,String>> set = map.entrySet();
    for(Map.Entry<Integer,String> entry : set){
        // 验证结果:HashMap集合key部分元素:无序不可重复。
        System.out.println("Key: "+ entry.getKey() + "   Value: " + entry.getValue());
    }

运行结果:
在这里插入图片描述

三、对比HashSet:

实例:

// 演示一下HashSet集合特点
        Set<String> strs = new HashSet<>();

        // 添加元素
        strs.add("hello3");
        strs.add("hello4");
        strs.add("hello1");
        strs.add("hello2");
        strs.add("hello3");
        strs.add("hello3");
        strs.add("hello3");
        strs.add("hello3");

        // 遍历
        /*
        1、存储时顺序和取出的顺序不同。
        2、不可重复。
        3、放到HashSet集合中的元素实际上是放到HashMap集合的value部分了。
         */
        for(String s : strs){
            System.out.println(s);
        }

运行结果:
在这里插入图片描述
总结:
1、 Set和Map的关系:

Set(继承自Collection集合)
Set代表一种集合元素无序、不可重复的集合,Map代表一种由多个key-value对组成的集合。

Map关系集合
Map集合的key特征:所有key不能重复,key之间没有顺序。Map集合的所有key将具有set集合的特征。
对Set做改造可将Set改造成Map集合;

2、HashSet和HashMap的区别和联系:

对于HashSet,系统采用Hash算法决定集合元素的存储位置;对于HashMap,系统将value当成key的附属物,系统根据hash算法决定key的存储位置,value总是紧随key存储。

HashSet通过封装一个HashMap对象来存储所有的集合元素,所有放入HashSet中的集合元素实际上由HashMap的key来保存,而HashMap的value则存储了一个PERSENT,它是一个静态的Object对象。

HashSet的add()方法添加元素时实际上转变为调用HashMap的put()方法来添加key-value对,当新放入的hashmap的Entry中的key与集合中原有的Entry的key相同(hashCode()返回值相等,通过equals比较也返回true)时,新添加的Entry的value将覆盖原来Entry的value,但key不会有任何改变。如果向hashSet中添加一个已经存在的元素,新添加的集合元素不会覆盖已有的集合元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值