在现实中,往往会遇见这种问题:
根据姓名查询考试成绩;
在通讯录中,根据姓名查询联系方式;
不重复集合,即需要先搜索关键字是否已经在集合中;
这些情况,可能会在查找中进行一些插入和删除的操作,即动态查找,此时就需要使用Map和Set。
一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称为key-value的键值对:Map中存储的就是key-value的键值对,Set中只存储了key。
List,Set,Map的区别(易考):
List(对付顺序的好帮手):存储的元素是有序的、可重复的;
Set(注重独一无二的性质):存储的元素是无序的、不可重复的;
Map(用Key来搜索的专家):使用键值对存储,里面的key-value映射的规则是Hash函数映射,一个key只能映射到一个value
1.Map的使用
Map
是一个接口类,该类没有继承自
Collection
,该类中存储的是
<K,V>
结构的键值对,并且
K
一定是唯一的,不
能重复
。
1.1 Map.Entry<k,v>
Map内部实现的用来存放<key,value>键值对映射关系的内部类,该内部类中主要提供<key,value>的获取,value的设置以及key的比较方式。
方法 | 解释 |
K getKey() | 返回entry中的key |
V getValue() | 返回entry中的value |
V setValue(V value) | 将键值对中的value替换为指定value |
Map.Entry<k,v>并未提供设置Key的方法。
1.2 Map的常用方法
1. Map
是一个接口,不能直接实例化对象
,如果
要实例化对象只能实例化其实现类
TreeMap
或者HashMap
2. Map
中存放键值对的
Key
是唯一的,
value是可以重复的
3. 在
Map
中插入键值对时,
key
不能为空,否则就会抛
NullPointerException
异常
,但是
value可以为空
4. Map
中的
Key
可以全部分离出来,存储到
Set
中
来进行访问
(
因为
Key
不能重复
)。
5. Map
中的
value
可以全部分离出来,存储在
Collection
的任何一个子集合中
(value
可能有重复
)。
6. Map中键值对的
Key
不能直接修改,
value
可以修改,如果要修改
key
,只能先将该
key删除掉,然后再来进行
重新插入。
7. TreeMap
和
HashMap
的区别
Map底层结构 | TreeMap | HashMap |
底层结构 | 红黑树 | 哈希桶 |
插/删/查时间复杂度 | O(log2N) | O(1) |
是否有序 | 关于Key有序 | 无序 |
线程安全 | 不安全 | 不安全 |
比较和覆写 | key必须能够比较,否则会抛出ClassCastException异常 | 自定义类型需要覆写equals和hashCode方法 |
插/删/查区别 | 需要进行元素比较 | 通过哈希函数计算哈希地址 |
应用场景 | 需要key有序场景下 | key是否有序不关心,需要更高的时间性能 |
1.3 Set的常见方法
1. Set
是继承自
Collection
的一个接口类
2. Set
中只存储了
key
,并且要求
key
一定要唯一
3. Set
的底层是使用
Map
来实现的,其使用
key
与
Object
的一个默认对象作为键值对插入到
Map
中的
4. Set
最大的功能就是对集合中的元素进行去重
5.
实现
Set
接口的常用类有
TreeSet
和
HashSet
,还有一个
LinkedHashSet
,
LinkedHashSet
是在
HashSet
的基础
上维护了一个双向链表来记录元素的插入次序。
6. Set
中的
Key
不能修改,如果要修改,先将原来的删除掉,然后再重新插入
7. Set
中不能插入
null
的
key
。
8. TreeSet
和
HashSet
的区别
Set底层结构 | TreeSet | HashSet |
底层结构 | 红黑树 | 哈希桶 |
插/删/查时间复杂度 | O(log2N) | O(1) |
是否有序 | 关于Key有序 | 无序 |
线程安全 | 不安全 | 不安全 |
比较和覆写 | key必须能够比较,否则会抛出ClassCastException异常 | 自定义类型需要覆写equals和hashCode方法 |
插/删/查区别 | 按照红黑树的特性来进行插入和删除 | 1.先计算key哈希地址2.然后进行插入和删除 |
应用场景 | 需要key有序场景下 | key是否有序不关心,需要更高的时间性能 |