数据结构之Map&Set

简介: 数据结构之Map&Set

1667919156551.jpg

一、概念、场景及模型


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 )

https://docs.oracle.com/javase/8/docs/api/java/util/Map.html

1.关于Map的说明


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

2.关于Map.Entry的说明


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

方法 说明

getKey()

返回entry 中的key

V getValue ()

返回 entry 中的 value

V setValue(V value)

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


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

3.Map的常用方法

方法 说明

get(Object key)

返回key 对应的value

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循序遍历:

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

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


5.试题案例


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

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


三、Set的使用


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


Set的官方文档:

Set (Java Platform SE 8 )

https://docs.oracle.com/javase/8/docs/api/java/util/Set.html

1.关于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.试题案例


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

public int singleNumber(int[] nums) {
            HashSet<Integer> set = new HashSet<>();
            for (int i = 0; i < nums.length; i++) {
                if (!set.contains(nums[i])){
                    set.add(nums[i]);
                }else {
                    set.remove(nums[i]);
                }
            }
            for (int i = 0; i < nums.length; i++) {
                if (set.contains(nums[i])){
                    return nums[i];
                }
            }
            return -1;
        }
相关文章
|
2月前
|
存储 Java
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
97 2
|
2月前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
77 2
|
20天前
|
算法
你对Collection中Set、List、Map理解?
你对Collection中Set、List、Map理解?
55 18
你对Collection中Set、List、Map理解?
|
14天前
|
存储 缓存 安全
只会“有序无序”?面试官嫌弃的List、Set、Map回答!
小米,一位热衷于技术分享的程序员,通过与朋友小林的对话,详细解析了Java面试中常见的List、Set、Map三者之间的区别,不仅涵盖了它们的基本特性,还深入探讨了各自的实现原理及应用场景,帮助面试者更好地准备相关问题。
51 20
|
1月前
|
存储 C++ 容器
【C++】map、set基本用法
本文介绍了C++ STL中的`map`和`set`两种关联容器。`map`用于存储键值对,每个键唯一;而`set`存储唯一元素,不包含值。两者均基于红黑树实现,支持高效的查找、插入和删除操作。文中详细列举了它们的构造方法、迭代器、容量检查、元素修改等常用接口,并简要对比了`map`与`set`的主要差异。此外,还介绍了允许重复元素的`multiset`和`multimap`。
30 3
【C++】map、set基本用法
|
1月前
|
存储 算法 C++
【C++】unordered_map(set)
C++中的`unordered`容器(如`std::unordered_set`、`std::unordered_map`)基于哈希表实现,提供高效的查找、插入和删除操作。哈希表通过哈希函数将元素映射到特定的“桶”中,每个桶可存储一个或多个元素,以处理哈希冲突。主要组成部分包括哈希表、哈希函数、冲突处理机制、负载因子和再散列,以及迭代器。哈希函数用于计算元素的哈希值,冲突通过开链法解决,负载因子控制哈希表的扩展。迭代器支持遍历容器中的元素。`unordered_map`和`unordered_set`的插入、查找和删除操作在理想情况下时间复杂度为O(1),但在冲突较多时可能退化为O(n)。
22 5
|
2月前
|
存储 Java 开发者
Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效
【10月更文挑战第19天】在软件开发中,随着项目复杂度的增加,数据结构的组织和管理变得至关重要。Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,帮助开发者告别混乱,提升代码质量。
34 1
|
2月前
|
存储 JavaScript 前端开发
Set、Map、WeakSet 和 WeakMap 的区别
在 JavaScript 中,Set 和 Map 用于存储唯一值和键值对,支持多种操作方法,如添加、删除和检查元素。WeakSet 和 WeakMap 则存储弱引用的对象,有助于防止内存泄漏,适合特定场景使用。
|
2月前
|
存储 缓存 Java
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
【用Java学习数据结构系列】HashMap与TreeMap的区别,以及Map与Set的关系
44 1
|
2月前
|
存储 安全
【数据结构】Set的使用与注意事项
【数据结构】Set的使用与注意事项
30 2