map的两种遍历方式、hashMap的底层原理

Map

储存键值对,保证键值的唯一性是通过HashMap中hash表

map集合常用方法

image-20211016200856468

获取方法

image-20211016201003218

遍历

通过KeySet方法,获取Map集合中所有的键的集合

通过values方法,获取Map集合中所有的值的集合

  • Map第一种遍历方法
    • 通过KeySet()方法获取所有键的集合
    • 遍历键的集合,获取所有的键,使用增强for循环实现
    • 根据键去找值,通过get(Object key)方法实现
      public void test1(){
      		//创建集合对象
      		Map<String,String> cities = new HashMap<String,String>();
      		//put(K key,V value)将指定的值与该映射中的指定键相关联
      		cities.put("吉林省", "长春市");
      		cities.put("黑龙江省", "哈尔滨市");
      		cities.put("辽宁省", "沈阳市");
      		
      		//获取所有键的集合。用keySet()方法实现
              Set<String> keySet = cities.keySet();
              //遍历键的集合,获取到每一个键。用增强for实现
              for (String key : keySet) {
                  //根据键去找值。用get(Object key)方法实现
                  String value = cities.get(key);
                  System.out.println("key="+key + ",value=" + value);
              }
      
      	}
      
      
  • Map第二种遍历方法
    • 通过entrySet()方法获取所有键值对的集合
    • 遍历键的集合,获取所有的键值对,使用增强for循环实现
    • 根据键和值去找键值对,通过getKey()方法获取Key;通过getValue()方法获取value
      public void test1(){
      		//创建集合对象
      		Map<String,String> cities = new HashMap<String,String>();
      		//put(K key,V value)将指定的值与该映射中的指定键相关联
      		cities.put("吉林省", "长春市");
      		cities.put("黑龙江省", "哈尔滨市");
      		cities.put("辽宁省", "沈阳市");
      
      		//获取所有键值对对象的集合
      		Set<Entry<String,String>> ens = cities.entrySet();
      		//遍历键值对对象的集合,得到每一个键值对对象
      		for(Entry<String,String> en : ens){
      			//根据键值对对象获取键和值
                  String key = en.getKey();
                  String value = en.getValue();
                  System.out.println("key="+key + ",value=" + value);
      		}
      		
      	}
      
      

HashMap的底层实现

hashMap的底层实现是哈希表

  • 哈希表底层采用数组+链表实现,即使用链表处理冲突。

  • 同一hash值的链表都存储在一个链表里。

  • 但是当位于一个桶(数组)中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。

  • 而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

  • 简单的来说,哈希表是由数组+链表+红黑树JDK1.8增加了红黑树部分)实现的,如下图所示。

image-20210801184212720

HashMap的put(k,v)实现

  1. 将k,v封装到Node(节点)对象中
  2. 底层会调用k的hashCode()方法得出hash值
  3. 通过哈希算法,将hash值转换为数组的下标,
  4. 如果该下标的位置上没有任何元素,就把这个Node添加到这个位置上。
  5. 如果该下标的位置上有链表,此时,就会将k和链表上的每个节点的k进行比较(使用equals()方法)
  6. 如果equals()方法返回的是false,则把这个新的节点添加到链表的末尾
  7. 如果equals()方法返回的是true,那么这个节点的value就被覆盖

HashMap的get(k)实现

  1. 调用hashCode()方法得出哈希值,通过哈希算法将其转换为数组的下标
  2. 通过上面获取的下标,可以快速定位到该下标的位置
  3. 如果该下标的位置上什么都没有,就返回null
  4. 如果该下标的位置上有单向链表,那么就会拿get(k)方法里面的k,与单向链表上的每一个节点比较(通过equals()方法)
  5. 如果通过4的equals()方法,返回的值是false,则get()方法返回null
  6. 如果通过4的equals()方法,返回的值是true,该节点的value就是需要找的value值,get()方法返回这个value值
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

?abc!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值