目录
1- Map集合特点 2- Map接口的常用方法 3- HashMap集合 4- TreeMap集合 5- Hashtable集合 6- Map集合遍历的三种方法
Map集合特点
Map
接口没有继承其他接口,和Collection单列接口不同,Map是双列的,并且以键值对的形式存储;
存储时元素的键(Key)不可重复,并且可以使用null值(Value)作为键。
Map的数据结构只对键(Key)生效,与值(Value)无关。
Map接口的常用方法
向集合中添加元素
代码语言:javascript复制// 如果Map中不存在这个Key,则返回null
// 如果Map中已经存在这个Key,则返回这个Key对应的Value,并设置这个Key对应的Value为最新值
map.put(K key,V value)
根据键删除集合中的元素
代码语言:javascript复制// 根据键删除集合中的元素
map.remove(Object key)
根据键(Key)获取Value
代码语言:javascript复制map.get(Object key)
判断集合是否包含指定键
代码语言:javascript复制// 返回Boolean值
map.containsKey(Object key)
清空集合
代码语言:javascript复制map.clear()
获取集合的长度
代码语言:javascript复制// 返回一个int类型值
map.size()
HashMap
HashMap可以说是最常用的Map集合,从如上继承图中可以看到,它实现了三个接口,继承了一个抽象类。
Serializable
和Cloneable
都是标识接口,他们的作用分别是标识可序列化和可克隆。
AbstractMap
抽象类则是Map子类的共性方法抽取,以避免代码重复。
HashMap不是线程安全的,如果对线程安全有要求的话建议使用concurrent
包下的ConcurrentHashMap集合。
HashMap底层数据结构
JDK1.8之前是数组 链表
的数据结构
JDK1.8之后则有增加了红黑树的数据结构,变成了数组 链表 红黑树
详细数据结构内容请参考这篇内容:HashMap深度解析
TreeMap
在Map集合框架中,除了HashMap以外,TreeMap也是常用到的集合对象之一。
TreeMap底层数据结构
相较HashMap,TreeMap底层使用红黑树的结构,而HashMap在达到一定条件后才会转为红黑树的结构。
TreeMap继承关系
TreeMap实现的接口中Cloneable
和Serializable
都是标识性接口,前者标识TreeMap可以被克隆,后者标识TreeMap可被序列化。
实现的NavigableMap
接口意味着TreeMap拥有相较HashMap更强的元素搜索能力。实现的AbstractMap
抽象类作用与HashMap无异,都是避免代码重复而做的共性抽取。
需要注意的是,TreeMap在存储NULL键时会出现空指针异常,这是因为存入数据的时候,put方法调用了String类的compareTo
方法,导致了空指针的异常。如果需要存储NULL键,则需要我们自定义Comparator
比较器,让它强制存储NULL键。
Hashtable
注意Hashtable没有使用驼峰命名,t
为小写而非大写。
Hashtable的操作几乎与HashMap一致,主要区别在于Hashtable是线程安全。另外Hashtable的键和值都不接受NULL,会返回空指针异常。由于Oracle官方预计将其废弃,所以不建议使用Hashtable,如果对线程安全要求比较高,推荐使用concurrent
包下的ConcurrentHashMap,这里就不做更多描述。
Map集合遍历方法
这里介绍三种常用方法
第一种方法:使用ForEach方式遍历
利用entrySet方法返回一个Entry的Set集合,而Set集合是单列集合,我们可以遍历这个Set集合来做到遍历整个Map集合。
代码语言:javascript复制for(Map.Entry<String,Object> entry:map.entrySet()){
System.out.println(entry.getKey() "-" entry.getValue());
}
第二种方法:使用迭代器遍历
Set集合可以获取一个迭代器,执行这个迭代器则可以遍历整个Map集合。
代码语言:javascript复制Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry next = (Map.Entry)iterator.next();
System.out.println(next.getKey() "--" next.getValue());
}
第三种方法:使用Lambda表达式遍历
这种方式是最简单的方式,由Map接口提供的方法,而这个方法的底层还是使用ForEach来进行遍历元素。
代码语言:javascript复制map.forEach((k,v)->{
System.out.println(k "--" v);
});