第18天 map

本文详细介绍了JavaMap接口的使用,重点讲解了HashMap和Hashtable的区别,包括key-value存储、线程安全性、容量设置、扩容策略以及hash碰撞处理。
摘要由CSDN通过智能技术生成

Map

Map接口中存储的是key(键)和value(值),由键值对组成的。每一个键都不重复。值是可以重复的。
key-value称之为键值对
将每一个键值对看作一个对象,抽取出一个代表键值对的类,叫做Map.Entry

//创建一个映射
Map<String,String> map = new HashMap<>();
//添加数据
map.put("温人豪"(key),"是谁"(value));
//根据key获取value,获取key值不存在返回null
sout(map.get("温人豪"))
//根据key移除元素
map.remove("温人豪")
//判断key是否存在
map.containKey("温人豪")
//判断values是否存在
map.containsValue("是谁")
//清空map
map.clear();
//获取元素个数
map.size();
//获取所有的value
Collection<String> values = map.values();
//获取所有的key
1) Set<String> strings = map.keySet();
2) for (String key : strings){
		sout(key);//获取键
		sout(map.get(key));//获取值
		}

// 获取所有键值对
1)Set<Map.Entry<String,String>> entries = map.entrySet();
  sout(entries)
2) for (Map.Entry<String,String> entry : entries){
		sout(entry);
		sout(entry.getKey());
		sout(entry.getValue());
		}


//快速遍历map
map.forEach((key,value) -> System.out.println(key + ":"+value));


//判断map是否为空
sout(map.isEmpty());


map 使用方法的练习

输入一个字符串,统计每一个字符出现的次数 aaabbccdd

最初想法:先设置一个空的map,从左到右依次遍历,这些值是是键值对中的值,出现的次数是键值对中的键、从第一个开始,并与map中的键比较,如果没有则创立一个新的键,如果有,则在值处加1,

HashMap

  1. key和value 允许 null
  2. 是线程不安全的映射
  3. 输出的内容是无序的,位置可能发生改变
  4. 当第一次put元素时,会创建一个长度为16的Node类型的数组,默认的阈值是12,默认的初始容量是16,默认的加载因子是0.75
  5. 初始化容量是2的n次方的形式
  6. 底层是数组+链表+红黑树
  7. 默认扩容是容量翻一倍
HashMap() : 创建一个空的HashMap
HashMap(int initialCapacity) : 指定初始容量,初始容量一定是2的n次方的形式
HashMap(int initialcapacity,float loadFactor) : 使用指定的初始容量和加载因子构造一个空HashMap

源码总结:

  1. 如果链表长度大于8,数组长度小于64,或者大于默认阈值12。数组会进行一次扩容。数组长度翻倍,并且对数据重新进行高低位分配。链表的长度会减少。数组长度大于64,链表长度大于8会转为红黑树
  2. HashMap初始化容量永远都是2的n次方格式
  3. 扩容时是容量范围,如果原来的桶上是链表,那么扩容后要么放在原来的索引处,要么是原来索引位置+原来的数组长度处
  4. 当扩容时,如果桶上是一个红黑树,经过运算长度小于等于6,会变成链表。
  5. hashMap的key一般不要使用自定义类型,如果要使用,重写hashCode方法。
    自定义类型是根据地址为判断依据,如果存两个数值一样的数,并不会有问题。应该改成属性值相同,地址不同认为是一个。需要重写equals,Objects的equals默认判断的是两个地址值,需要改成属性相同就返回true。

断点

打断点之后点debug,程序会运行到打断点的前一行,打断点的那一行还没有执行

快捷键
F8:程序往下执行一行后停止
F9:直接跳过没有打断点的代码,跳到打断点的代码处停止

hash碰撞的情况

  1. key的值相同,key的hash一样,把新的值替换为旧的值
  hashMap.put("1",1000);
  hashMap.put("1",2000);
  1. key值不同,hash值相同。会对桶中的结点一个一个比较,直到链表结点的next是两个不同的next是null,key会被映射到哈希表的同一个位置,也就是同一个“桶”中
hashMap("Ma",3000)
hashMap("NB",4000)
  1. key值不同,hash值不同。(n-1)&hash后的值相同。这两个不同的key会被放置在同一个桶中的链表或红黑树上
hashMap.put("a",5000);
hashMap.put("b",5000);
hashMap.put("c",5000);
hashMap.put("d",5000);
hashMap.put("e",5000);
hashMap.put("aerg",5000);
hashMap.put("agr",5000);
hashMap.put("aeweg",5000);
hashMap.put("aarg",5000);

Hashtable

  1. Hashtable的key和value不能是null,如果是null,抛出空指针异常。
  2. 线程是安全的
  3. 默认初始容量是11,默认加载因子是0.75
  4. 指定的初始化容量指定多少就是多少
  5. 默认扩容是先扩大一倍再加1
  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值