当前位置:   article > 正文

Map和Set_mapset

mapset

目录

一,搜索

1.概念和场景

2. 模型

二,Map

1.关于Map.Entry的说明

2.Map的常用方法

注意事项:

TreeMap 和 HashMap 的区别:

红黑树介绍:

代码示例:

三,Set

1.Set的概念

2.Set的常用方法

注意事项:

TreeSet和HashSet的区别:

代码示例:


一,搜索

1.概念和场景

  • Map和set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。以前常见的搜索方式有:
  1. 直接遍历,时间复杂度为O(N),元素如果比较多效率会非常慢
  2. 二分查找,时间复杂度为 ,但搜索前必须要求序列是有序的
  • 上述排序比较适合静态类型的查找,即一般不会对区间进行插入和删除操作了
  • 现实问题中的查找都存在动态查找的可能,因此,Map和Set是一种适合动态查找的集合容器

2. 模型

一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称之为Key-value的键值对,所以模型会有两种:

  • 纯 key 模型
  1. 有一个英文词典,快速查找一个单词是否在词典中
  2. 快速查找某个名字在不在通讯录中
  • Key-Value 模型
  1. 统计文件中每个单词出现的次数,统计结果是每个单词都有与其对应的次数:<单词,单词出现的次数>
  2. 同一个名字的使用人数,就是名字重复的人数:<名字,重复的人数>
  • Map中存储的就是key-value的键值对,Set中只存储了Key 

二,Map

从图中可以看到Map是一个接口,该接口没有继承自Collection,该接口中存储的是<K,V>结构的键值对,并且K一定是唯一的,不能重复

1.关于Map.Entry<k,v>的说明

  • Map.Entry<K, V> 是Map内部实现的用来存放<key, value>键值对映射关系的内部类,该内部类中主要提供了<key, value>的获取,value的设置以及Key的比较方式

  • Map.Entry<K,V>并没有提供设置Key的方法

2.Map的常用方法

注意事项:

  • Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
  • Map中存放键值对的Key是唯一的,value是可以重复的
  • 在Map中插入键值对时,key不能为空,否则就会抛NullPointerException异常,但是value可以为空
  • Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)
  • Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)
  • Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入

TreeMap 和 HashMap 的区别:

Map底层结构TreeMapHashMap
底层结构红黑树哈希桶
插入/删除/查找时间复杂度O(\log_{2}N)O(1)
是否有序关于Key有序无序
是否线程安全线程不安全线程不安全
插入/删除/查找区别需要进行元素比较通过哈希函数计算哈希地址
比较与覆写key必须能够比较,否则会抛出
ClassCastException异常
自定义类型需要覆写equals和
hashCode方法
应用场景需要Key有序场景下Key是否有序不关心,需要更高的时间性能

红黑树介绍:

  • TreeMap底层是红黑树,红黑树底层是二叉搜索树 + 一系列的条件限制
  • 每个结点都有颜色,要么是红色要么是黑色
  • 最长路径中的结点个数不超过最短路径中结点个数的二倍
  • 根节点必须是黑色
  • 每条路径中的黑色结点数量相等
  • 不能有连着的红色结点
  • “叶子结点”必须为黑色(这个叶子结点指的是所有结点的空节点)

代码示例:

  1. import java.util.*;
  2. public class MyMap {
  3. public static void main(String[] args) {
  4. Map<String,Integer> m = new TreeMap<>();
  5. m.put("张三",1);
  6. m.put("李四",2);
  7. m.put("王五",3);
  8. System.out.println(m.get("张三")); //获取key的value值
  9. System.out.println(m.getOrDefault("赵六",0)); //如果key不存在,返回默认值
  10. System.out.println(m.size()); // 获取m的有效键值对
  11. m.put("张三",100); //若key已经存在,新的value会代替之前的value,有效键值对并不会增加
  12. System.out.println(m.size());
  13. //m.put(null,10); // key不能为空,但是,value可以为空
  14. System.out.println(m.get("张三")); //获取新的value
  15. if(m.containsKey("张三")){
  16. System.out.println("张三存在");
  17. }else{
  18. System.out.println("张三不存在");
  19. }
  20. if(m.containsValue(100)){
  21. System.out.println("100存在");
  22. }else{
  23. System.out.println("100不存在");
  24. }
  25. Set<String> s = m.keySet();
  26. for (String s1: s) {
  27. System.out.print(s1 + " ");
  28. }
  29. System.out.println();
  30. Collection<Integer> c = m.values();
  31. for (Integer c1 : c ) {
  32. System.out.print(c1 + " ");
  33. }
  34. System.out.println();
  35. Set<Map.Entry<String,Integer>> me = m.entrySet();
  36. for (Map.Entry<String,Integer> me1 : me) {
  37. System.out.print(me1 + " ");
  38. }
  39. System.out.println();
  40. }
  41. }

三,Set

1.Set的概念

  • Set不同于Map的是,Set继承自Collection,Set中只存放了key
  • Set的底层也有两种TreeSet和HashSet

2.Set的常用方法

方法解释
boolean add(E e)添加元素,但重复元素不会被添加成功
void clear()清空集合
boolean contains(Object o)判断 o 是否在集合中
Iterator<E> iterator()返回迭代器
boolean remove(Object o)删除集合中的 o
int size()返回set中元素的个数
boolean isEmpty()检测set是否为空,空返回true,否则返回false
Object[] toArray()将set中的元素转换为数组返回
boolean containsAll(Collection<?> c)集合c中的元素是否在set中全部存在,是返回true,否则返回
false
boolean addAll(Collection<? extends
E> c)
将集合c中的元素添加到set中,可以达到去重的效果

注意事项:

  • Set是继承自Collection的一个接口类
  •  Set中只存储了key,并且要求key一定要唯一
  • Set的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的
  • Set最大的功能就是对集合中的元素进行去重
  • 实现Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序
  • Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
  • Set中不能插入null的key

TreeSet和HashSet的区别:

Set底层结构TreeSetHashSet
底层结构红黑树哈希桶
是否有序关于Key有序不一定有序
线程安全不安全不安全
插入/删除/查找区别按照红黑树的特性来进行插入和删除1. 先计算key哈希地址 2. 然后进行
插入和删除
比较与覆写key必须能够比较,否则会抛出
ClassCastException异常
自定义类型需要覆写equals和
hashCode方法
应用场景需要Key有序场景下Key是否有

代码示例:

  1. import java.util.*;
  2. public class TestSet {
  3. public static void main(String[] args) {
  4. Set<String> s = new TreeSet<>();
  5. // add(key): 如果key不存在,则插入,返回true
  6. // 如果key存在,返回false
  7. boolean isIn = s.add("apple");
  8. s.add("orange");
  9. s.add("peach");
  10. s.add("banana");
  11. System.out.println(s.size());
  12. System.out.println(s);
  13. isIn = s.add("apple");
  14. // add(key): key如果是空,抛出空指针异常
  15. //s.add(null);
  16. // contains(key): 如果key存在,返回true,否则返回false
  17. System.out.println(s.contains("apple"));
  18. System.out.println(s.contains("watermelon"));
  19. // remove(key): key存在,删除成功返回true
  20. // key不存在,删除失败返回false
  21. // key为空,抛出空指针异常
  22. s.remove("apple");
  23. System.out.println(s);
  24. s.remove("watermelon");
  25. System.out.println(s);
  26. // 抛出空指针异常
  27. // s.remove(null);
  28. Iterator<String> it = s.iterator();
  29. while(it.hasNext()){
  30. System.out.print(it.next() + " ");
  31. }
  32. System.out.println();
  33. }
  34. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/202053?site
推荐阅读
相关标签
  

闽ICP备14008679号