深入聊一聊JDK中的Map和Set
作者:你们的伟仔
1. 基础知识
集合Java.util包下的常用子类,集合无非就是各种数据结构的应用。集合存在的目的就是为了将数据高效的进行读写,无论哪种具体的集合无外乎CURD。
Map和set是一种专门用来进行搜索的容器或者数据结构(核心应用场景:高效搜索/查找)。
Map和Set是 一种适合动态查找的集合容器。
Set集合只能保存单个的元素。集合中所有元素是唯一的不重复的。
Map集合一次保存一个键值对(key = value)这种映射对象。
数学中的映射其实就是Java中的Map集合,存储的都是一个key对于一个value的映射关系。
在Map映射关系中,key值唯一的,value值可以重复。
Collection --> 单个元素保存的父接口。
List --> 可以保存重复的单个元素
Set --> 保存单个不重复元素。
Queue --> 队列接口,操作受限的线性表。
Deque --> 双端队列,使用此接口来表示栈或者队列。
2.模型
一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称之为Key-value的键值对,所以 模型会有两种:
1. 纯 key 模型,比如:
有一个英文词典,快速查找一个单词是否在词典中
2. Key-Value 模型,比如:
统计文件中每个单词出现的次数,统计结果是每个单词都有与其对应的次数:<单词,单词出现的次数>
梁山好汉的江湖绰号:每个好汉都有自己的江湖绰号
而Map中存储的就是key-value的键值对,Set中只存储了Key。
3.Map的使用
Map:存储的key-value键值对,若需要根据不重复的key去查找value的内容,使用Map集合。
4.Map接口的使用
常用的两个子类:
HashMap底层基于哈希表(数组+链表)的实现。
TreeMap底层基于二分搜索平衡树的实现。
(1)元素的添加和更新操作
a.元素的添加和更新操作都是一个方法。put(K key,V value):将键值对key和value保存到当前的Map集合中。若key值已经存在,则更新value的值。
1.Map集合中,key值不能重复,若put时,发现key重复,则会将当前Map中对应的value值更新为此时的value的值。
2.value值可以重复。
3.在Map集合中,键值对是"无序"的,元素的保存顺序和添加顺序无关。
4.关于Map集合中保存null值
a.HashMap:key和value都可以为null。key值是唯一的,只能保存一个null的key。
b.在TreeMap中key值不能为null,value值可以为null。并且key值必须实现Compareable接口或者通过TreeMap的构造方法传入比较器对象!换句话说:保存在TreeMap的Key值必须是可比较的。TreeMap也是无序的(添加顺序和保存顺序不是一一对应)
c.在Map集合中,元素的添加顺序和保存顺序相同的子类是LinkedHaspMap。
且LinkedHaspMap有序的,添加顺序和保存顺序一一对应。
LinkedHashMap:给普通的HaspMap加了个链表,这个链表就保存了元素的添加顺序。
在开发中可以改造LinkedHaspMap做LRU缓存。
(2)在Map集合中查询/搜索特定的值
get(K key):根据key值搜索对应的value值,若没有对应的key值,返回null。
getOrDefault(K key,V defaultVal):根据key值搜索map中对应的value值,若没有找到,返回默认值defaultValue。getOrDefault方法常和put方法搭配使用,简化代码逻辑。
boolean.containsKey(K key):在当前Map集合中是否包含指定的key值。
boolean containsValue(V value):在当前Map集合中是否包含指定的value值。
(3) 删除Map中指定的value和key
remove(K key):删除key值对应的键值对对象,返回删除之前的value值。
remove(K key,V value):删除指定的key值以及对应的value值对象,返回布尔值表示是否删除成功。
clear():清空Map表(将当前Map中所有键值对对象一次清空)。
(4) Map集合的遍历
Map集合的遍历是比较低效的。
for-each循环只能用于Iterable接口以及子类,Map集合和Iterable接口毫无关系。
要想进行Map集合的遍历,必须先将Map转为Set集合。
Map接口在存储键值对对象时,内部存储的一个个都是Map.Entry对象。
1.将Map对象转为Set对象,Set对象的内部就存储Map的一个个键值对Entry对象。
转为Set对象之后,就可以方便的使用for-each循环进行遍历。
其中的每个元素就是Map的Entry对象!
也可以分别输出key值和value值,这时重复的value也会重复输出。
5.Set集合的使用
Set与Map主要的不同有两点:Set是继承自Collection的接口类,Set中只存储了Key。
add(E e):向当前Set集合中添加一个新的元素e,若e不存在则成功添加,返回true;若e存在,添加失败,返回false。因此方便的使用Set集合的add方法做去重处理。
boolean remove(object o):删除指定元素o (boolean返回值类型)
boolean contains(object o):查询当前Set集合中是否包含元素o
在Set集合中没有提供元素的修改方法。要向修改,先将这个元素删了,再添加新值。
6.Set集合和Map集合的关系
Set是保存单个不重复元素的集合,Map是保存一对键值对对象的集合。
Set的常用子类如HashSet,TreeSet,内部就使用的是对应的Map对象。
HashSet元素就在HashMap的key值上保存。
TreeSet元素就在TreeMap的key值上保存。
总结
到此这篇JDK中Map和Set的文章就介绍到这了,更多相关JDK的Map和Set内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!