网站首页 > java教程 正文
写在前面:
视频是什么东西,有看文档精彩吗?
视频是什么东西,有看文档速度快吗?
视频是什么东西,有看文档效率高吗?
诸小亮:下面我们学习——Map
张小飞:这个我知道,Map——双列集合,也称映射、字典,没错吧
诸小亮:不错,那你可知道它存储什么样的数据?
张小飞:Map是用来存储键值(key,value)数据的
诸小亮:嗯嗯, 说的不错,Map 可以说是开发中最常使用的集合了,主要特点:
1. 一次存储一对儿数据,称为键值对
2. 能够保证key的唯一性
1. 常用方法
诸小亮:既然你已经提前看过了,可否说一说?
张小飞:嗯,我试试吧
张小飞:首先 Map 其实是一个接口,更 Collection 类似,里面定义了很多共性的方法
诸小亮:那,都有哪些方法呢?
张小飞:这可不少,另外因为 Map 是个接口,所以用它的具体实现类 HashMap 演示
1.1. put
张小飞:put(key,value):添加元素,每次添加一对儿数据
public static void main(String[] args) throws Exception {
//创建map对象,一般都声明泛型,限制存储的数据类型
Map<String, String> map = new HashMap<>();
//添加元素
map.put("yase","zhenji");
System.out.println(map);
}
结果:
诸小亮:我记得 put 方法有返回值啊
张小飞:是的,返回的是指定key对应的值,比如:
public static void main(String[] args) throws Exception {
Map<String, String> map = new HashMap<>();
map.put("yase","zhenji");
//因为map的key不能重复,所以新值覆盖老值,但是会返回老值
String str = map.put("yase", "xishi");
System.out.println(str);
}
结果:
1.2. putAll
putAll(Map<k,v> map):把指定参数中的数据,都添加到当前 map 中
演示:省略
1.3. get
get(key):根据key获取value
1.4. containsKey
containsKey(key):是否包含指定的key,true:是,false:否
1.5. containsValue
containsValue(value):是否包含指定的value,true:是,false:否
1.6. isEmpty
isEmpty():判断是否空的,true:是,false:否
1.7. remove
remove(key):删除指定的key,返回对应的value
结果:
1.8. clear
clear():清空整个map
结果:
1.9. keySet()
keySet():把map中的所有key放到一个Set集合中返回,常用来遍历整个map
public static void main(String[] args) throws Exception {
Map<String, String> map = new HashMap<>();
map.put("yase","zhenji");
map.put("lvbu","diaochan");
map.put("lixin","xishi");
//遍历整个map
Set<String> keys = map.keySet();
for(String key : keys) {
System.out.println(map.get(key));
}
}
结果:
1.10. entrySet()
entrySet():返回包含映射关系的 Set 集合,也是常用的一种遍历方式
public static void main(String[] args) throws Exception {
Map<String, String> map = new HashMap<>();
map.put("yase","zhenji");
map.put("lvbu","diaochan");
map.put("lixin","xishi");
// entrySet 返回Set集合,存储的是Map.Entry类型的对象
// 一个Map.Entry就是map中的一对儿key,value
Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String,String> en : entries){
//一个 Map.Entry 中只包含一对key,value
System.out.println(en.getKey()+"----"+en.getValue());
}
}
结果:
1.11. values
values():把map中的所有value放到一个集合中返回
结果:
问题:为什么 values() 方法返回的不是 Set 集合?
答案:因为 map 中的 value 可能重复,而 Set 会自动去重
2. HashMap
诸小亮:我看你上面用的都是 HashMap 这个子类,对这个的挺多的啊
张小飞:还好吧,因为传说工作中 HashMap 使用的最频繁,所以一直用这个
诸小亮:嗯,你说的不错,工作中确实它使用的最多,那你能说说它的底层结构吗?
2.1. 数据结构
张小飞:当然可以,数据结构是:可变数组 + 链表,其实 HashSet 内部的就是 HashMap
诸小亮:嗯,功课做的不错,继续说
张小飞:其数组,默认长16,当元素个数超过 数组大小 * loadFactor 时,数组会扩容一倍
诸小亮:这个 loadFactor 是?
张小飞:loadFactor 是加载因子,默认值=0.75 ,表示当元素数量到 12 的时,数组扩容
诸小亮:那么,如何避免数组频繁的扩容呢?
张小飞:创建 HashMap 对象时,可以指定初始用量的大小,也就是可变数组的长度
诸小亮:然后呢?
张小飞: 一般建议,如果能提前确定需要存储的元素数量,在创建 HashMap 对象时候就要指定大小,避免
HashMap 频繁扩容,比如:
假如需要存储1200个元素,那么大小应该是:1200 / 0.75 = 1600;
因为是必须是2的N次方,最终值应该是比1600大且最接近的2的N次方的整数:2048
注意:其实在执行 new HashMap<>(1600); 时,其内部自动计算出2048,并设置为初始值
诸小亮:嗯,很不错,超乎我的意料
诸小亮:不过,JDK8 之后,HashMap底层做了优化啊
张小飞:是的,JDK8 之后,HashMap 的底层数据结构为:数组+链表+红黑树
- 当数组的长度大于 64 且链表长度大于 8 时,链表会转换成红黑树结构
诸小亮:为什么在链表长度大于 8 的时候转换?
张小飞:有两点原因
1. 根据默认的算法,HashMap中链表的长度>8的概率是非常低的,小于千万分之一
设置为 8 的原因是:不希望把链表转换为红黑树
2. 链表长度大于 8 后平均查询效率没有红黑树高
2.2. 无序
诸小亮:什么是无序?
张小飞:就是,在 put 数据时,key的存放无法保证顺序,比如:
public static void main(String[] args) throws Exception {
HashMap<String, String> map = new HashMap<>(1200);
map.put("daji","女仆咖啡");
map.put("yase","心灵战士");
for(Map.Entry<String,String> en : map.entrySet()){
//一个 Map.Entry 中只包含一对key,value
System.out.println(en.getKey()+"----"+en.getValue());
}
}
结果:
,取出的顺序,跟存放的顺序不同
2.3. 空key 和 空value
张小飞:Map中,允许 null 作为key,null 作为 value,比如:
public static void main(String[] args) throws Exception {
Map<String, String> map = new HashMap<>();
map.put(null,"xishi");//key可以是null
System.out.println(map.get(null));
map.put("yase",null);//value也可以是null
System.out.println(map.get("yase"));
}
结果:
3. LinkedHashMap
诸小亮:说一说 LinkedHashMap 吧
张小飞:LinkedHashMap——是 HashMap 的子类,它最大的特点
- 可以保证 key 存放时候的顺序
public static void main(String[] args) throws Exception {
Map<String, String> map = new LinkedHashMap<>();
map.put("yase","zhenji");
map.put("lvbu","diaochan");
map.put("lixin","xishi");
Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String,String> en : entries){
System.out.println(en.getKey()+"----"+en.getValue());
}
}
结果:
,按照存放的顺序取出key,value
诸小亮:为什么它可以保证顺序呢?
张小飞:原理跟 LinkedHashSet 一样
4. TreeMap
诸小亮:我记得,还有一个 TreeMap 吧
张小飞:是的,TreeMap——是 Map 的具体子类
数据结构:
- 二叉树结构,其实 TreeSet 内部的就是 TreeMap
- 内部自动对 key 进行排序,比如:
public static void main(String[] args) throws Exception {
Map<String, String> map = new TreeMap<>();//注意,这里是无参数的构造方法
//这时候存储的key,必须实现Comparable接口
map.put("yase","zhenji");
map.put("lvbu","diaochan");
map.put("lixin","xishi");
map.put("anqila","xiaohongnv");
System.out.println(map);
}
结果:
张小飞:TreeMap还有一个构造方法:TreeMap(Comparator<? super K> comparator);
- 使用它创建对象时,需要提供一个 Comparator 比较器
5. HashTable
张小飞:还有一个HashTable——也是map的具体子类
诸小亮:它更 HashMap 有什么区别?
张小飞:HashMap就是为替代它而生,主要区别:
1. Hashtable 是不允许键或值为 null ,HashMap 的键值都可以为 null
2. HashTable 都是同步方法
3. HashMap 的初始容量为:16,Hashtable 初始容量为:11
4. HashMap 扩容规则为当前容量翻倍,Hashtable 扩容规则为当前容量翻倍 +1
猜你喜欢
- 2024-09-22 JavaScript中的数组遍历forEach()与map()方法以及兼容写法
- 2024-09-22 golang(go语言) map如何按照插入的顺序遍历? #go语言
- 2024-09-22 关于Java8中Map的一些骚操作你会那些....
- 2024-09-22 Apachec工具commons-collections4遍历Map
- 2024-09-22 Map遍历的四种方法效率对比(遍历map的三种方式)
- 2024-09-22 Map的遍历方式(map遍历remove)
- 2024-09-22 Scala set和map(scala菜鸟教程)
- 2024-09-22 关于Java Map,你应该掌握哪8个问题?
- 2024-09-22 Java HashMap 遍历方式性能探讨(遍历hashmap的三种方式)
- 2024-09-22 HashMap 的遍历方式+性能分析(hashmap遍历效率最高的方法)
你 发表评论:
欢迎- 最近发表
-
- class版本不兼容错误原因分析(class更新)
- 甲骨文Oracle公司为Java的最新LTS版本做出改进
- 「版本发布」Minecraft Java开发版 1.19.4-pre1 发布
- java svn版本管理工具(svn软件版本管理)
- 我的世界1.8.10钻石在第几层(我的世界1.7.2钻石在哪层)
- Java开发高手必备:在电脑上轻松切换多个JDK版本
- 2022 年 Java 开发报告:Java 8 八年不到,开发者都在用什么?
- 开发java项目,选择哪个版本的JDK比较合适?
- Java版本选型终极指南:8 vs 17 vs 21特性对决!大龄程序员踩坑总结
- POI Excel导入(poi excel导入附件)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)