【Java】Map和Set

Map和Set

  • [两种数据模型:Key 与 Key-Value](#两种数据模型:Key 与 Key-Value)
  • [Map 详解:键值对的映射容器](#Map 详解:键值对的映射容器)
    • [Map 的概念](#Map 的概念)
    • [Map.Entry<K, V> ⭐](#Map.Entry<K, V> ⭐)
    • [Map 常用 API](#Map 常用 API)
    • Map的特点
    • [HashMap vs TreeMap](#HashMap vs TreeMap)
  • [Set 详解:唯一元素的集合](#Set 详解:唯一元素的集合)
    • [Set 的概念](#Set 的概念)
    • [Set 常用 API](#Set 常用 API)
    • [Set 的特点](#Set 的特点)
    • [HashSet vs TreeSet](#HashSet vs TreeSet)

两种数据模型:Key 与 Key-Value

  • 纯 Key 模型只存储关键字,用于判断"某个元素是否存在"。典型场景包括:判断单词是否在词典中、检查用户名是否已被注册。

  • Key-Value 模型:不仅存储关键字,还关联一个对应的值。典型场景包括:根据学号查学生信息、统计单词出现次数。

简单来说:Set 对应纯 Key 模型,Map 对应 Key-Value 模型 。在 Java 集合框架中,两者都是接口,需要通过具体实现类来使用 :

  • Map 实现类:HashMap、TreeMap(均实现 Map 接口)
  • Set 实现类:HashSet、TreeSet(均实现 Set 接口)

Map 详解:键值对的映射容器

Map 的概念

在深入 HashMap 和 TreeMap 之前, 需要先明确 Map 接口的核心定义与约束

  • Map 是一个接口类,它没有继承自 Collection 接口,这与 List、Set 不同。
  • Map 中存储的是 <K, V> 结构的键值对,并且 Key 一定是唯一的,不能重复 。当使用 put 方法放入相同的 key 时,新的 value 会覆盖旧的 value。

Map.Entry<K, V> ⭐

Map.Entry<K, V> 是 Map 内部实现的用来存放 <key, value> 键值对映射关系的内部类 。当遍历 Map 时,拿到的就是一个个 Entry 对象。

该内部类主要提供了以下方法:

方法 解释
K getKey() 返回 entry 中的 key
V getValue() 返回 entry 中的 value
V setValue(V value) 将键值对中的 value 替换为指定 value

注意Map.Entry<K, V> 并没有提供设置 Key 的方法。这意味着 Map 中键值对的 Key 不能直接修改,如果要修改 Key,只能先将该 key 对应的映射删除,然后再插入新的 key-value 对。

Map 常用 API

以下是 Map 接口中最核心的方法,无论使用 HashMap 还是 TreeMap,这些 API 都是通用的:

方法 解释
V get(Object key) 返回 key 对应的 value,若 key 不存在则返回 null
V getOrDefault(Object key, V defaultValue) 返回 key 对应的 value,若 key 不存在则返回默认值 defaultValue
V put(K key, V value) 设置 key 对应的 value,若 key 已存在则覆盖并返回旧值
V remove(Object key) 删除 key 对应的映射关系,返回被删除的 value
Set<K> keySet() 返回所有 key 的不重复集合(因为 key 唯一)
Collection<V> values() 返回所有 value 的可重复集合(value 可能重复)
Set<Map.Entry<K, V>> entrySet() 返回所有的 key-value 映射关系
boolean containsKey(Object key) 判断是否包含指定的 key
boolean containsValue(Object value) 判断是否包含指定的 value

Map的特点

  • Map 不能直接实例化:Map 是一个接口,必须通过其实现类(如 TreeMap 或 HashMap)来实例化对象。

  • Map下的类不能使用迭代器进行遍历。

  • Key 唯一,Value 可重复:这是 Map 最核心的特性。

  • 关于 null 值的支持差异

    • TreeMap :插入键值对时,Key 不能为空 (会抛出 NullPointerException),Value 可以为空。
    • HashMap :Key 和 Value 都可以为空
  • Key 的分离与访问:Map 中的 Key 可以全部分离出来,存储到 Set 中进行访问(因为 Key 不能重复,正好符合 Set 的特性)。

  • Value 的分离与访问:Map 中的 value 可以全部分离出来,存储在 Collection 的任何一个子集合中(因为 value 可能有重复)。

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

HashMap vs TreeMap

特性 HashMap TreeMap
底层结构 哈希表(数组+链表+红黑树) 红黑树
时间复杂度 O(1) O(log n)
元素顺序 无序 按键的自然顺序或比较器排序
null 支持 key 和 value 均可为 null key 不能为 null,value 可以为 null
比较要求 自定义对象需重写 hashCode() 和 equals() key 必须实现 Comparable 或传入 Comparator
  • 不关心顺序、追求极致性能 → 选 HashMap
  • 需要按键有序遍历 → 选 TreeMap

从源码深入理解HashMap和TreeMap

Set 详解:唯一元素的集合

Set 的概念

在深入 HashSet 和 TreeSet 之前,需要先明确 Set 接口的核心定义与约束

  • Set 是继承自 Collection 的一个接口类,这意味着它拥有 Collection 的所有方法,同时有自己的特性约束。
  • Set 的核心特征是元素不可重复 ,向 Set 中添加已存在的元素会被直接忽略 。

Set 常用 API

以下是 Set 接口中最核心的方法,无论使用 HashSet 还是 TreeSet,这些 API 都是通用的:

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

Set 的特点

  • Set 中只存储了 Key,并且要求 Key 一定要唯一,不能重复
  • Set 最大的功能就是对集合中的元素进行去重
  • Set 中的 Key 不能修改,如果要修改,只能先将原来的删除掉,然后再重新插入

HashSet vs TreeSet

特性 HashSet TreeSet
底层结构 HashMap(只用 key,value 为固定常量) TreeMap(只用 key)
时间复杂度 O(1) O(log n)
元素顺序 无序 有序(自然顺序或比较器)
null 支持 允许一个 null 元素 不允许 null(会抛 NullPointerException)
比较要求 需重写 hashCode() 和 equals() 元素必须实现 Comparable 或传入 Comparator
相关推荐
敲代码的彭于晏36 分钟前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev2 小时前
ButterKnife → ViewBinding
android·java·kotlin
像我这样帅的人丶你还18 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩18 小时前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
tntxia18 小时前
Mybatis的日志输入
java
亦暖筑序20 小时前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
用户298698530141 天前
Java 实现 Word 文档加密与权限解除
java·后端
Yeats_Liao1 天前
14:Servlet中的页面跳转-Java Web
java·后端·架构
未秃头的程序猿1 天前
告别"if-else地狱"!Java 21模式匹配,代码优雅了10倍
java·后端·面试
鹤望兰6751 天前
字节跳动国际支付-后端开发-三面面经
java