当前位置: 首页 > news >正文

哈希法(Java)

在算法中,哈希法(散列哈希表)是一种通过「键 - 值」映射快速访问数据的方法,核心是利用哈希函数将键映射到内存地址,实现 O (1) 级别的查找效率。常用的哈希结构有数组Set 和 Map,它们的适用场景和特性各有不同,下面详细讲解:

一、哈希数组(Hash Array)

本质

用数组的下标作为「键」,数组的作为「值」,直接通过下标访问数据。

特点
  • 优势:访问速度最快(直接通过下标定位,无需哈希函数计算),实现简单。
  • 限制
    1. 键必须是整数(因为数组下标只能是整数)。
    2. 键的范围必须有限且已知(否则数组会过大,浪费空间)。
适用场景
  • 元素值范围较小且为整数(如 0~1000),例如:
    • 统计数字出现次数(如两数之和、数组交集)。
    • 判断元素是否存在(如判断一个数是否在数组中)。
示例

java

运行

// 统计 nums 中每个数字的出现次数(假设数字范围 0~100)
int[] count = new int[101]; // 下标 0~100 对应数字 0~100
for (int num : nums) {count[num]++; // 直接用数字作为下标,累加次数
}

二、哈希集合(Hash Set)

本质

存储不重复的元素(只有键,无值),底层通过哈希表实现,支持快速判断元素是否存在。

特点
  • 优势
    1. 自动去重(相同元素只会存储一次)。
    2. 支持任意类型的元素(整数、字符串等)。
  • 限制
    1. 只能判断元素是否存在,无法存储额外信息(如次数、索引)。
    2. 空间复杂度较高(哈希表需要额外空间存储哈希值)。
适用场景
  • 需要去重或判断元素是否存在的场景,例如:
    • 数组去重。
    • 检查两个数组的交集(只需要元素本身,不需要次数)。
示例

java

运行

// 数组去重
int[] nums = {1, 2, 2, 3, 3, 3};
Set<Integer> set = new HashSet<>();
for (int num : nums) {set.add(num); // 自动去重,最终 set 中为 {1,2,3}
}

三、哈希映射(Hash Map)

本质

存储键 - 值对(Key-Value),可以通过键快速查找对应的值,底层也是哈希表实现。

特点
  • 优势
    1. 键可以是任意类型(整数、字符串等),值可以存储额外信息(如次数、索引)。
    2. 支持复杂的映射关系(如元素→索引、元素→出现次数)。
  • 限制
    1. 键不能重复(重复会覆盖旧值)。
    2. 空间复杂度较高(比数组大)。
适用场景
  • 需要存储键和对应值的场景,例如:
    • 两数之和(存储元素→索引,快速查找互补元素的位置)。
    • 统计元素出现次数(键为元素,值为次数)。
示例

java

运行

// 存储元素及其索引
int[] nums = {2, 7, 11, 15};
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {map.put(nums[i], i); // 键:元素值,值:元素索引
}
// 查找元素 7 的索引:map.get(7) → 返回 1

四、三者的核心区别

结构存储内容键的类型限制适用场景优势劣势
哈希数组下标→值(次数)必须是整数元素范围小且为整数的统计速度最快,空间最省键类型和范围受限
Hash Set不重复的元素任意类型去重、判断元素是否存在自动去重,使用简单无法存储额外信息
Hash Map键 - 值对任意类型复杂映射关系(如元素→索引)功能最灵活,支持多信息空间开销较大

五. 「无序」与「有序」结构的对比

无序结构(Unordered)有序结构(Ordered)
HashSetHashMapLinkedHashSetLinkedHashMap(保证插入顺序)
无顺序保证,基于哈希表实现保证顺序(插入顺序或自然排序),部分基于链表 / 红黑树实现
查找、插入、删除效率高(O (1))效率略低(如 TreeMap 为 O (log n))

总结

  • 优先用数组:当元素是整数且范围有限时(空间和速度最优)。
  • 优先用Set:只需去重或判断存在性,无需额外信息时。
  • 优先用Map:需要存储键和对应的值(如索引、次数)时。
http://www.dtcms.com/a/321987.html

相关文章:

  • 【数据结构】排序(sort) -- 计数排序
  • wstool和git submodule优劣势对比
  • select ... for update阻塞
  • 【感知机】感知机(perceptron)学习算法例题及详解
  • 任务管理器如何查看详细的命令行和路径?
  • 安科瑞能源管理系统在某新材料公司光储充一体化项目上的应用
  • 【C++空指针革命】nullptr:告别NULL的终极解决方案与底层实现剖析
  • 在超算中心,除了立式机柜(rack-mounted)还有哪些形式?
  • 官方Windows系统部署下载工具实践指南
  • 遥测自跟踪天线系统组成、特点、功能、工作流程
  • 【普通地质学】地质年代与地层系统
  • 无人机SN模块运行与功能详解
  • Vibe coding现在能用于生产吗?
  • 什么是0.8米分辨率卫星影像数据?
  • C++ WonderTrader源码分析之自旋锁实现
  • nflsoi 8.8 题解
  • CF每日3题(1400-1700)
  • 第9章 AI 安全、可解释性与伦理合规
  • 3天落地企业级应用,JNPF+AI重塑开发效率
  • sqli-labs靶场less46-less50
  • 传送带包裹漏检率↓78%!陌讯动态感知模型在物流分拣的实战优化
  • dMSA 滥用 (BadSuccessor) 导致权限升级:使用 ADAudit Plus 监控关键属性更改
  • Python使用LLM把自然语言翻译成SQL语句
  • 线程组和线程池的基本用法
  • 深入理解 SwiftUI 布局:VStack、HStack 和表单控件全解析
  • 电脑和手机访问网站,自动检测跳转不同网站
  • 将2小时的财报OCR识别录入缩短至5分钟,如何实现财报智能OCR录入
  • 创建一个Vue3项目
  • TLF35584芯片功能总结
  • Python基础语法练习