数据结构之Map&Set

系统管理员 2024-04-01 08:42 159阅读 0赞

文章目录

  • 一、概念、场景及模型
  • 二、Map的使用

    • 1.关于Map的说明
    • 2.关于Map.Entry的说明
    • 3.Map的常用方法
    • 4.Map的遍历方式
    • 5.试题案例
  • 三、Set的使用

    • 1.关于Set的说明
    • 2.试题案例

c24c7205d0f94659b5d1095dbdca5d0e.png


一、概念、场景及模型

Map set是一种专门用来进行搜索的容器或者数据结构,Map和Set是一种适合动态查找的集合容器。TreeMap和TreeSet集合背后的数据结构就是搜索树,红黑树。其中TreeSet底层就是一个TreeMap。

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

  1. key 模型

  2. Key-Value 模型

Map 中存储的就是 key-value 的键值对, Set 中只存储了 Key

二、Map的使用

Map的官方文档:Map (Java Platform SE 8 )icon-default.png_t_M85Bhttps://docs.oracle.com/javase/8/docs/api/java/util/Map.html1.关于Map的说明

Map是一个接口类,该类没有继承自Collection,该类中存储的是结构的键值对,并且K一定是唯一的,不能重复 因为底层是二叉搜索树。

2.关于Map.Entry的说明

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




















方法 说明


K getKey()


返回 entry 中的 key


V getValue()


返回 entry 中的 value


V setValue(V value)


将键值对中的value替换为指定value

注意: Map.Entry 并没有提供设置 Key 的方法

3.Map的常用方法












































方法 说明


V get(Object key)


返回 key 对应的 value


V getOrDefault(Object key, V defaultValue)


返回 key 对应的 value,key 不存在,返回默认值


V put(K key, V value)


设置 key 对应的 value


V remove(Object key)


删除 key 对应的映射关系


Set<K> keySet()


返回所有 key 的不重复集合


Collection<V> values()


返回所有 value 的可重复集合


Set<Map.Entry<K, V>> entrySet()


返回所有的 key-value 映射关系


boolean containsKey(Object key)


判断是否包含 key


boolean containsValue(Object value)


判断是否包含 value

注意:

  1. Map 是一个接口,不能直接实例化对象,如果 要实例化对象只能实例化其实现类 TreeMap 或者 HashMap

  2. Map 中存放键值对的 Key 是唯一的, value 是可以重复的

  3. Map 中的 Key 可以全部分离出来,存储到 Set 来进行访问(因为Key不能重复)。

  4. Map 中的 value 可以全部分离出来,存储在 Collection 的任何一个子集合中(value可能有重复)。

  5. Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。

  6. TreeMap和HashMap的区别












































Map TreeMap HashMap
底层结构 红黑树 哈希桶


插入/删除/查找时间


复杂度
O(logN)

O(1)


是否有序


关于Key有序


无序


线程安全


不安全


不安全


插入/删除/查找区别


需要进行元素比较


通过哈希函数计算哈希地址


比较与覆写


key必须能够比较,否则会抛出 ClassCastException异常


自定义类型需要覆写equals和 hashCode方法


应用场景


需要Key有序场景下


Key是否有序不关心,需要更高的时间性能

4.Map的遍历方式

使用最多也最简单的是for循序遍历:

  1. HashMap<Integer,Integer> map = new HashMap<>();
  2. map.put(1,1);
  3. map.put(2,2);
  4. int[] arr = new int[2];
  5. int k = 0;
  6. for (Map.Entry<Integer,Integer> entry:map.entrySet()) {
  7. arr[k++] = entry.getKey();
  8. }

其实还有使用迭代遍历map、使用keySet迭代遍历map、使用entrySet遍历map这几种方式,但是觉得使用比较麻烦,直接使用for循环比较方便。

5.试题案例

统计10W个数据当中,每个数据出现的次数以及对应的关系。

  1. public static void func3(int[] array) {
  2. HashMap<Integer,Integer> map = new HashMap<>();
  3. //1、遍历原来的数据,统计每个数据出现的次数
  4. for (int i = 0; i < array.length; i++) {
  5. int key = array[i];
  6. if(map.get(key) == null) {
  7. map.put(key,1);
  8. }else {
  9. int val = map.get(key);//key出现的 次数
  10. map.put(key,val+1);
  11. }
  12. }
  13. for (Map.Entry<Integer,Integer> entry: map.entrySet()) {
  14. System.out.println("key: "+entry.getKey()+" 出现了:"+entry.getValue()+"次!");
  15. }
  16. }

三、Set的使用

Set与Map主要的不同有两点:Set是继承自Collection的接口类,Set中只存储了Key。

Set的官方文档:Set (Java Platform SE 8 )icon-default.png_t_M85Bhttps://docs.oracle.com/javase/8/docs/api/java/util/Set.html1.关于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中,可以达到去重的效果

注意:

  1. Set是继承自Collection的一个接口类

  2. Set中只存储了key,并且要求key一定要唯一

  3. Set的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的

  4. Set最大的功能就是对集合中的元素进行去重

  5. 实现Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。

  6. Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入

  7. Set中不能插入null的key,而Map则可以插入空的key。

2.试题案例

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

  1. public int singleNumber(int[] nums) {
  2. HashSet<Integer> set = new HashSet<>();
  3. for (int i = 0; i < nums.length; i++) {
  4. if (!set.contains(nums[i])){
  5. set.add(nums[i]);
  6. }else {
  7. set.remove(nums[i]);
  8. }
  9. }
  10. for (int i = 0; i < nums.length; i++) {
  11. if (set.contains(nums[i])){
  12. return nums[i];
  13. }
  14. }
  15. return -1;
  16. }

#

发表评论

表情:
评论列表 (有 0 条评论,159人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数据结构结构体复习

    为什么出现结构体?   为了表示一些复杂的数据,一些基本数据类型无法满足要求, 当要用一个变量描述一个对象的多个属性时,普通的内置数据类型是表示不了的,这个时候就可以用

    相关 数据结构

    什么是栈 从栈的操作特性上来看,栈是一种 “操作受限”的线性表,只允许在一端插入和删除数据,且满足先进后出、后进先出的特性。 实现一个栈 栈可以用数组或链表来实现

    相关 数据结构绪论

    本文主要介绍数据结构中的一些基本知识,例如数据结构得划分、数据类型、算法等。 接下来的博客将详细介绍数据结构中的链表、栈和队列、树、查找、排序等算法。 数据结构 1.

    相关 数据结构

    数据结构栈的相关学习: 简介 限定仅在表尾进行插入和删除操作的线性表。允许插入和删除的一端成为栈顶,另一端成为栈低,不含任何元素的栈成为空栈,栈又称为先进先出的线性表