【Java基础】Map集合系列

2022-05-12 19:59:21 浏览数 (1)

目录

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集合,从如上继承图中可以看到,它实现了三个接口,继承了一个抽象类。

SerializableCloneable都是标识接口,他们的作用分别是标识可序列化和可克隆。

AbstractMap抽象类则是Map子类的共性方法抽取,以避免代码重复。

HashMap不是线程安全的,如果对线程安全有要求的话建议使用concurrent包下的ConcurrentHashMap集合。

HashMap底层数据结构

JDK1.8之前是数组 链表的数据结构

JDK1.8之后则有增加了红黑树的数据结构,变成了数组 链表 红黑树

详细数据结构内容请参考这篇内容:HashMap深度解析

TreeMap

在Map集合框架中,除了HashMap以外,TreeMap也是常用到的集合对象之一。

TreeMap底层数据结构

相较HashMap,TreeMap底层使用红黑树的结构,而HashMap在达到一定条件后才会转为红黑树的结构。

TreeMap继承关系

TreeMap实现的接口中CloneableSerializable都是标识性接口,前者标识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);
});

0 人点赞