(点击跳转即可哦)
文章目录
Map和Set
概念
Map和Set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。
主要的数据结构:
二分搜索树 ---------> TreeMap/TreeSet
哈希表 ---------> HashMap/HashSet
模型
一般把搜索的数据称为关键字(key)和关键字对应的称为值(Value),称为Key-value的键值对,所以模型会有两种:
纯Key模型
比如:
有一个英文字典,快速查找一个单词是否在字典中
快速查找某个名字在不在通讯录中
Key-Value模型:
统计文件中每个单词出现的次数,统计结果是每个单词都有与之对应的次数:<单词,单词出现的次数>
梁山好汉的江湖绰号:每个好汉都有自己的江湖绰号
Map中存储的就是K、key-value的键值对,Set中只存储了key
关于Map的说明
Map是一个接口类,该类没有继承自Collection,该类中存储的是<k,v>结构的键值对,并且K一定是唯一的,不能重复。
Map的常用方法说明
//返回key对应的value
V get(Object key)
//返回key对应的Value,key不存在,返回默认值
V getOrDefault(Object key,V defaultValue)
//添加一个新的键值对,若key不存在,就新增一个Map.Entry对象,保存在Map
//若key已经存在,修改原来的value为新的value,返回修改前的value
V put(K key, V value)
//删除 key 对应的映射关系
V remove(Object key)
//返回所有 key 的不重复集合
Set<K> keySet()
//返回所有 value 的可重复集合
Collection<V> values()
//返回所有的 key-value 映射关系
Set<Map.Entry<K, V>> entrySet()
//判断是否包含 key
boolean containsKey(Object key)
//判断是否包含 value
boolean containsValue(Object value)
//返回当前Map接口中所有的Key值集合 -》 返回值是一个Set
//key不能重复 -》 Set接口中就保存的 不重复元素
Set<K> keySet();
//返回当前Map接口中所有的value值集合 -》 返回值是一个Collection
//Value可以重复
Collection<V> values();
-
Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类
TreeMap
或者HashMap
-
Map中存放键值对的Key是唯一的,value是可以重复的
-
在Map中插入键值对时,key不能为空,否则就会抛
NullPointerException
异常,但是value可以为空 -
Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)。
-
Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)
-
Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行 重新插入。
Map集合的遍历:实际上就是取出一对一对的元素
Map中的键值对这个类型 -> Map.Entry
-> 一个个键值对
map.entrySet()
=> 这个方法的返回值就是一组键值对 对象 Map.Entry
<K key,V Value>
Map.Entry
=>
entry.getKey()
=> 当前键值对的key
entry.getValue()
=> 当前键值对的Value
for(Map.Entry<Integer,Integer> entry : map.entrySet()){
System.out.println(entry.getKey() + " = " + entry.getValue());
}
Set
Set : 是Collection接口的子接口,一次保存一个元素,和List集合最大的区别在于 Set集合保存的元素不能重复。
使用Set集合来进行去重处理!!!!
Set的常用方法说明
boolean add(E e);
添加一个元素,若该元素不存在则添加成功,返回true,若该元素已经存在,添加失败,返回false
boolean contains(Object o);
判断一个元素O是否在当前set中存在,存在返回true
boolean remove(Object o);
在Set集合中删除指定元素o,若该元素不存在,删除失败,返回false, 否则删除该元素,返回true
在set集合中,没有提供修改的方法,若需要修改元素,只能先把要修改的元素删除,再添加新元素。
遍历集合使用 for-each 循环即可
关于Map接口常见子类的添加问题
- Map接口中元素的添加顺序和元素的保存顺序没有必然联系。
Map<String,String> map = new HashMap<>();
//HashMap 中保存的元素顺序由hash函数来决定
Map<String,String> map = new TreeMap<>();
//由TreeMap中的compareTo方法决定
//要能使用TreeMap保存元素,该类必须要么实现Comparable 要么传入一个比较器
- 关于保存null值的说明
HashMap
的key 和 value 都能为null,若key为 null,有且只有一个
TreeMap
中 key 不能为 null,value 可以为 null
Leetcode-138 复制带随机指针的链表
import java.util.HashMap;
import java.util.Map;
/**
* 复制带随机指针的链表
*/
public class Leetcode_138 {
public Node copyRandomList(Node head) {
if(head == null){
return head;
}
Map<Node,Node> map = new HashMap<>();
//循环遍历原链表,创建新的节点并复制原链表的值,原链表对应新链表的元素
for (Node x = head; x != null; x = x.next) {
Node y = new Node(x.val);
map.put(x,y);
}
//遍历map集合,
for (Map.Entry<Node,Node> entry : map.entrySet()) {
//使该节点的 key的next,random对应key 映射到 该节点的value的next,random对应的 value
entry.getValue().next = map.get(entry.getKey().next);
entry.getValue().random = map.get(entry.getKey().random);
}
return map.get(head);
}
}
Leetcode-771 宝石与石头
//宝石和石头
public class Leetcode_771_Jewels_Stones {
public int numJewelsInStones(String jewels, String stones) {
Set<Character> set = new HashSet<>();
//在set集合中保存宝石
for (int i = 0; i < jewels.length(); i++) {
Character ch = jewels.charAt(i);
set.add(ch);
}
int j = 0;
//遍历石头的字符串,在宝石的set集合中查找是否有这个字符
for (int i = 0; i < stones.length(); i++) {
Character ch = stones.charAt(i);
if(set.contains(ch)){
j++;
}
}
return j;
}
}
要是对大家有所帮助的话,请帮我点个赞吧。