【Java学习—(21)Map和Set集合,以及相关的Leetcode问题】

(点击跳转即可哦)

java学习专栏

LeetCode刷题专栏



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();
  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删除掉,然后再来进行 重新插入。


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接口常见子类的添加问题

  1. Map接口中元素的添加顺序和元素的保存顺序没有必然联系。
Map<String,String> map = new HashMap<>();
//HashMap 中保存的元素顺序由hash函数来决定

Map<String,String> map = new TreeMap<>();
//由TreeMap中的compareTo方法决定
//要能使用TreeMap保存元素,该类必须要么实现Comparable 要么传入一个比较器
  1. 关于保存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;
    }
}

要是对大家有所帮助的话,请帮我点个赞吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值