目录
1 概念及场景
Map和Set的主要数据结构:二分搜索树 和 哈希表
Set :其实就是披着Set外衣的Map
也是Collection接口的子接口,一次保存一个元素,和List集合最大的区别在于,set集合保存的元素不能重复。
Set :使用Set集合来进行去重处理!!! ! !
其中List 和Set是Collection的子接口
Map接口:
Map集合和Set集合的基础使用
Set接口
Set:add功能
Set: contains功能
Set:remove功能
注释:Set集合中没有提供可以修改内容的set方法,也就是不能修改内容。
没有提供修改的方法 ===》若需要修改元素,只能先把要修改的元素删除,再添加新元素!! !
注释:在以后是使用Set就会发现根本不会会修改内容的必要
因为:Map和Set是天然的搜索语义。要使用这两个集合,百分之99%都是用在进行元素的查找工作。
遍历集合 使用 for-each 循环即可
Set基础功能测试:
package jcl;
import java.util.HashSet;
import java.util.Set;
//Set接口的基础使用
public class SetTest {
public static void main(String[] args) {
Set<Integer> set =new HashSet<>();
//添加元素
System.out.println(set.add(1));
System.out.println(set.add(1));
System.out.println(set.add(2));
System.out.println(set.add(3));
for(int i : set){
System.out.print(i + " ");
}
System.out.println();
System.out.println(set.contains(3));//是否有 3 这个元素
System.out.println(set.contains(4));//是否有 4 这个元素
System.out.println(set.remove(1));//删除 1这个元素
for(int i : set){
System.out.print(i + " ");
}
}
}
第二次添加相同元素时并没有成功,返回 false
Map接口
Map接口,保存的是一对 键值对 元素 key = value
Map:put功能
put有两个功能:新增 & 修改
添加一个新的键值对 ===》
若key不存在,就新增一个Map.Entry 对象,保存到Map中
若key已经存在,修改原来的value为新的value,返回修改前的value。
Map: get方法
Map:remove方法
Map:keySet方法
Map:values方法
注释:只要是Collection 的子类,都可以用 for——each 循环遍历
测试:put功能
打印所以value值
修改key对应的value值
删除操作:
关于Map接口常见子类的添加问题。
1.Map接口中元素的添加顺序和元素的保存顺序没有必然联系。
不像List,添加顺序和保存顺序一致,先添加1,1这个元素一定保存在2之前。逻辑连续
发现:打印的顺序并不是添加时的顺序
注释:Map里面覆写了toString方法,可以直接打印。
这个顺序的决定是由:HashMap中保存的元素顺序,由hash函数来决定
现在换成TreeMap类,打印发现任然是乱序
现在的顺序由:TreeMap中的compareTo方法决定
要能使用TreeMap保存元素,该类必须要么实现Comparable要么传入一个比较器
如果用TreeMap,此时传入的类没有覆写Comparable方法就会报错,类型转换异常
但是换成 HashMap 就没事了,因为它们底层实现的结构是不同的
2.关于保存null值的说明
对于HashMap来说,是可以保存Null空值的
此时的null也是key,有且只有一个
HashMap的key和value都能为null若key为null,有且只有一个
现在换成 TreeMap 来保存
TreeMap 保存,key不允许为空,value值可以为空
常用方法总结:
解释说明下这个方法:
下面这个方法的使用是什么意思?
解析:我想往Map集合里面插入key值为 i 的数值,后面要添value值,如果已经存在了对应的key值的话,就会把原本key对应的value值换成新添加key的value值。
map.getOrDefault(i, 0) + 1 :这样写的含义是,如果存在i对应的key,则这个方法符合key原本对应的value值。如果这个Map集合中不存在i的key,才返回 后面写的默认值 + 1.
如果是第一次出现 则是 0 + 1 = 1; 如果是第二次出现则会返回原来的value 1 + 1 = 2;
如果是第三次出现则是 2 + 1 = 3;相当于可以计算出现的频次。
做力扣题
这里用Map接口的特性就非常简单
题解:
第二题:
138. 复制带随机指针的链表 - 力扣(LeetCode)
思路一:链表解法
简单来说,先正常遍历链表,遇到一个节点就创建一个新节点,用尾插的方式。然后再次遍历链表,计算原链表的random指向节点的 偏移量 或者说相当于数组的 索引值。根据偏移量去新链表去连接就好了
思路二:巧用Map集合
Map集合保存的是key和value的映射关系
把原链表当初key,新链表当初value。用get方法,当输出key,返回value地址。
代码实现:用Map来解决,就非常的轻松。
class Solution {
public Node copyRandomList(Node head) {
//1. 遍历原链表,构造Map集合维护原链表节点和新链表节点的映射关系
//原1 = 新1
Map<Node, Node> map = new HashMap<>();
for(Node x = head; x != null; x = x.next){
Node node = new Node(x.val);
map.put(x, node);//原1 = 新1 两者建立关系
}