Java笔记20——Map和Set

目录

1 概念及场景

Map集合和Set集合的基础使用

Set接口

Map接口

 关于Map接口常见子类的添加问题。

做力扣题

Map和Set使用官方文档

搜索树(BST)

操作-插入

操作-查找 

3.按照先序遍历的方式打印当前的BST

​编辑

操作-删除(难点)

在BST中删除任意值val

​编辑

哈希表

这就是哈希函数的本质 

小总结

​编辑 解决哈希冲突的方法:闭散列、开散列

对于—般场景下的哈希函数的设计

基于开散列方式实现的哈希表(这个代码非常重要)

这里有个概念叫:负载因子


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接口的特性就非常简单

136. 只出现一次的数字 - 力扣(LeetCode)

题解: 

第二题:

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 两者建立关系
        }
        
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值