常用数据结构特点对比
| 数据结构 | 底层实现 | 核心特点 | 典型场景 |
|---|---|---|---|
| 数组 (Array) | 连续内存空间 | 固定大小,随机访问快(O(1)),插入/删除需移动元素(O(n)) | 存储固定长度数据、快速查询场景 |
| List | 接口(无具体实现) | 有序、可重复、支持索引访问,提供增删改查方法 | 需动态调整大小且有序存储的场景 |
| ArrayList | 动态数组 | 基于数组实现,查询快(O(1)),扩容成本高(默认1.5倍),非线程安全 | 频繁读取、少量插入删除的场景 |
| HashMap | 数组+链表/红黑树 | 键值对存储,无序,键唯一(允许null键),查询/插入/删除平均O(1),非线程安全 | 快速键值映射(如缓存、统计频次) |
| HashSet | 基于HashMap实现 | 元素唯一,无序,基于哈希值存储,查询O(1),非线程安全 | 去重、快速判断元素是否存在 |
| Queue | 接口(无具体实现) | 先进先出(FIFO),仅允许在队首删除、队尾添加元素 | 任务排队、消息队列等场景 |
| Deque | 接口(双端队列) | 允许在两端插入/删除元素,支持FIFO和LIFO(栈)操作 | 双端操作场景(如滑动窗口) |
| PriorityQueue | 堆(默认小顶堆) | 元素按优先级排序(默认自然顺序),队首为最小/最大值,插入O(log n)、查询O(1) | 任务调度、Top K问题 |
关键差异总结
- 有序性:ArrayList、Queue、Deque、PriorityQueue 是有序的(ArrayList按插入顺序,PriorityQueue按优先级);HashMap、HashSet 是无序的。
- 唯一性:HashSet、HashMap 的键要求唯一;List、Queue、Deque 允许重复元素。
- 线程安全:以上均非线程安全,需手动同步(如
Collections.synchronizedList)或使用并发容器(如ConcurrentHashMap)。
哈希表的遍历方式取决于具体编程语言,但核心逻辑是遍历键值对,常见方式如下:
- 遍历所有键(Keys)
通过获取哈希表的所有键,再逐个访问对应的值。
- Python:
for key in hashmap.keys() - Java:
for (K key : hashmap.keySet()) - JavaScript:
for (let key of Object.keys(hashmap))
- 遍历所有值(Values)
直接遍历哈希表中存储的所有值,无需关注键。
- Python:
for value in hashmap.values() - Java:
for (V value : hashmap.values()) - JavaScript:
for (let value of Object.values(hashmap))
- 遍历键值对(Key-Value Pairs)
同时获取键和值,适用于需要同时处理两者的场景。
- Python:
for key, value in hashmap.items() - Java:
for (Map.Entry<K, V> entry : hashmap.entrySet()) - JavaScript:
for (let [key, value] of Object.entries(hashmap))
- 迭代器遍历(部分语言支持)
通过迭代器顺序访问哈希表元素,适合复杂逻辑控制。
- Java:
Iterator<Map.Entry<K, V>> iterator = hashmap.entrySet().iterator();while (iterator.hasNext()) { ... }
注意事项 - 无序性:多数哈希表(如Python的
dict、Java的HashMap)不保证遍历顺序与插入顺序一致。若需有序,可使用LinkedHashMap(Java)或Python 3.7+的dict(默认保留插入顺序)。 - 并发安全:遍历过程中修改哈希表可能导致异常(如Java的
ConcurrentModificationException),需加锁或使用并发容器。