哈希表

Set集合、Map集合

巧了我就是萌 提交于 2019-12-30 00:01:30
1、HashSet 集合 ● 特点: 底层数据结构:哈希表;存储、取出比较快;线程不安全,运行速度快(HashSet的底层是用HashMap实现的,因此查询效率较高,由于采用hashCode算法直接确定元素的内存地址,增删效率也挺高的) ● HashSet集合存储数据的结构(哈希表) 哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。 当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。 总结:保证HashSet集合元素的唯一

彩虹表

孤街浪徒 提交于 2019-12-29 23:42:43
彩虹表是一个用于 加密散列函数 逆运算的预先计算好的表, 为破解密码的散列值(或称哈希值、微缩图、摘要、指纹、哈希密文)而准备。一般主流的彩虹表都在100G以上。 这样的表常常用于恢复由有限集字符组成的固定长度的纯文本密码。这是空间/时间替换的典型实践, 比每一次尝试都计算哈希的暴力破解处理时间少而储存空间多,但却比简单的对每条输入散列翻查表的破解方式储存空间少而处理时间多。使用加salt的KDF函数可以使这种攻击难以实现。彩虹表是 马丁·赫尔曼 早期提出的简单算法的应用。 来源: https://www.cnblogs.com/xinhua219/p/10092492.html

集合Collection接口

早过忘川 提交于 2019-12-28 14:31:08
集合Collection接口: 是所有单列集合的最顶层接口 add()方法返回的意思是是否添加成功,添加动作是一定成功的。但是对于其他集合,添加不一定成功 分为list接口和set接口 List接口有序的(存储123,取出也是123),可以重复,有索引 有索引,可以使用普通for循环遍历 **set接口无序不可重复** 没有索引,不能使用带索引的方法,不能使用普通for循环遍历 哈希值:他是一个10进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来的地址,不是数据实际存储的物理地址) 在Object类有一个方法,可以获取对象的哈希值 HashSet的查询速度非常快,先把元素按照相同的哈希值分组,相同的哈希值把它挂到下面, 超过8位把他转换为红黑树 HashSet集合存储数据的结构(哈希表) jdk1.8之前:哈希表=数组+链表 jdk1.8版本之后:哈希表也等于数组加链表,链表变成了红黑树,数组+红黑树(提高查询的速度)如果链表长度超过了8位,那么就会把链表转换为红黑树 哈希表的特点:速度快 HashSet集合不允许重复的原理 只要是new的,就会把他们存储到堆内存当中,Set集合在调用add方法的时候,add方法会调用元素的hashCode方法和equals方法,通过hashCode方法计算元素的哈希值,判断元素是否重复 来源: CSDN 作者: 黄大仙Ol

散列表

家住魔仙堡 提交于 2019-12-27 01:04:05
散列表 散列表又称为哈希表,英文“Hash Table”。 散列表思想利用的是数组支持按照下标随机访问数据的特性。 散列函数 : 通过key,计算出value,value就是表示将数据放入数组的那个位置。 哈希冲突 : 不同的key,可能会得到相同的value,这是就产生了哈希冲突。 解决哈希冲突可以使用开放寻址法(线性探测、二次探测、双散列等)或者链地址法来解决。 装载因子 : 装载因子 = 散列表中存储的数据个数/散列表的大小 装载因子越大,说明散列表中的元素越多,空闲位置越少,散列冲突的概率就越大。不仅插入数据的过程要多次寻址或者拉很长的链,查找的过程也会因此变得很慢。 散列表的设计 散列函数 散列函数不能太复杂,否则计算哈希值的消耗太大 散列函数生成的值要尽可能随机且均匀分布,这样才能避免或者减小散列冲突 散列函数的设计还要考虑key的特性(长度、分布等),比如手机号,前几位重复率很高,后几位重复率较低,那么就可以取后几位作为value Redis中采用的散列函数有:times33和siphash算法,PHP中也采用了times33作为散列函数,还使用了或运算。 装载因子和动态扩容 当装载因子超过设置的阈值(一般是0.75)的时候,就需要对散列表重新扩容,这样就会导致所有数据的重新散列。如果当前散列表中的数据很大,需要把散列表扩容为原大小的2倍,则之前的数据都需要重新扩容

Bloom过滤器

喜你入骨 提交于 2019-12-27 00:20:56
提出一个问题 在我们细述Bloom过滤器之前,我们先抛出一个问题:给你一个巨大的数据集(百万级、亿级......),怎么判断一个元素是否在此数据集中?或者怎么判断一个元素不在此数据集中? 思考这个问题的时候,最先想到的可能是哈希表,在数据集规模较小的时候,这个方法是可行的,当然,数据集巨大的时候也可以采用分布式哈希表的方式。当数据集规模较大时,尤其是应用中只需要判断一个元素不在此数据集中的情况时,我们可以借鉴哈希表的思路,使用Bloom过滤器解决这个问题。既然我们只关心元素在不在,不关心元素值是什么,只要把元素映射为一个布尔值表示在不在就足够了。下面细述Bloom过滤器数据结构的设计。 Bloom过滤器数据结构 Bloom filter(布鲁姆过滤器)是用于测试元素成员资格的空间高效概率数据结构。数据结构以牺牲规定的假阳性率为代价实现了巨大的数据压缩。一个Bloom过滤器作为一个 m 位的数组全部设置为 0 。选择一组 k 个随机散列函数,在Bloom过滤器中添加元素时,元素将分别进行哈希散列,而对于每个 k 个输出,该索引处的相应的Bloom过滤器位将被设置为 1 。通过使用与之前相同的散列函数来完成Bloom过滤器的查询。如果在bloom过滤器中访问的所有 k 个比特被设置为 1 ,则这很可能表明该元素位于该集合中。删除元素只能通过废除Bloom过滤器并从头重新创建来完成

[LeetCode] 349. 两个数组的交集

此生再无相见时 提交于 2019-12-26 19:31:25
1 题目描述 给定两个数组,编写一个函数来计算它们的交集。 示例 1: 输入: nums1 = [1,2,2,1], nums2 = [2,2] 输出: [2] 示例 2: 输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出: [9,4] 说明: 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/intersection-of-two-arrays 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 2 解题思路 看到这道题的想法就是 设置两个去重之后的set,然后短的那个去长的那个里面查找, 看到题解之后 其实是不太明白的 题解的思路我也没有看太懂 然后翻了一下评论区, 很喜欢这个做法 觉得比较是个小白上手 假设长度小的数组为 less , 长度为 M;长度大的数组为 more , 长度为 N 使用长度小的数组建立哈希表 lessSet,用于匹配查找,时间复杂度为 O ( M ) , 最大额外空间复杂度为 O ( M ) . 循环长度大的数组,通过哈希表 lessSet 匹配与长度小的数组的交集,查找时间复杂度为 O ( 1 ) ,总的时间复杂度为 O ( N ) . 总体的时间复杂度为 O ( M + N

哈希表的特征和原理

老子叫甜甜 提交于 2019-12-25 23:54:38
哈希表也叫散列表,是一种神奇的结构,最大的特点就是快。它的结构有很多种,最流行、最容易理解的是:顺序表+链表的结构。主结构是长度可以动态变化的顺序表,每个顺序表的节点可以单独引出一个链表。哈希表的原理可以从以下三点阐述。 添加数据原理: 1)、计算哈希码,调用hashCode()方法,结果是一个int值,整数的哈希码取自身即可 2)、根据哈希码计算存储位置(数组的索引)【y = k(x) (除留取余法)存入哈希表】 3)、将数据存入指定位置,如果已经有元素存在,就是出现了冲突,需要沿着链表比较,有重复的元素,不存储。没有,就存储。 结论:添加快。时间复杂度O(1);无序。 查询数据的原理: 和添加过程一样,还是三步搞定。结论:查询快。 总结:哈希表的神奇之处在于按照内容查询,理想情况下可以达到数组索引查询的时间复杂度O(1)。核心在于其查询不是基于比较的,而是基于计算的。当存在冲突时,会降低效率。 如何减少冲突: 1)装填因子:哈希表的长度和表中的记录数的比例。超过装填因子就要扩容。不然冲突的概率会大大提高,从而影响性能。 2)哈希函数的选择 直接定址法 平方取中发 折叠法 除留取余法等 3)处理冲突的方法 链地址法 开放地址法 再散列法 建立一个公共溢出区 hashCode和equals()在哈希表添加查询中的作用: 1)hashCode():计算哈希码,是一个整数

Java8 HashMap源码分析

与世无争的帅哥 提交于 2019-12-25 05:42:14
java.util.HashMap 是最常用的java容器类之一, 它是一个线程不安全的容器. 本文对JDK1.8.0中的HashMap实现源码进行分析. HashMap 使用位运算巧妙的进行散列并使用链地址法处理冲突. 自JDK1.8后, 若表中某个位置元素数超过阈值 则会将其自动转换为红黑树来提高检索效率. HashMap 中的迭代器同样采用 fail-fast 机制, 即若迭代过程中容器发生结构性改变, 则会终止迭代. HashMap 主要有三个视图接口 keySet() , values() , entrySet() . 它们都是基于迭代器实现的, 并不实际存储数据. 哈希表 自JDK1.8.0开始HashMap使用静态内部类 Node 来存储键值对结构, 不再使用 Map.Entry : static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) {...} public final K getKey() { return key; } public final V getValue() { return value; }

day16

◇◆丶佛笑我妖孽 提交于 2019-12-24 06:30:54
集合框架 集合特点: 用于存储对象的容器 集合的长度是可变的 集合中不可以存储基本数据类型值 集合容器不断向上抽取,就形成了集合框架,框架的顶层为Collection接口 Collection的方法 添加: boolean add(Object obj);添加对象obj,添加成功返回true,反之返回false boolean addAll(Collection col);添加指定collection的所有元素 删除: boolean remove(Object obj) boolean removeAll(Collection col);移除两个集合中的相同元素 void clear();清空 包含: boolean contains(obj) boolean containsAll(col) boolean isEmpty();是否有元素 获取: int size();获取长度 Iterator iterator();取出元素,这是个接口 boolean retainAll(col);取两个collection的交集,与removeAll()的功能相反 Object[] toArray();将集合转换成数组 Iterator接口 next();取元素 boolean hasNext(); // Collection coll = new ArrayList ( ) coll .

Hash算法

人走茶凉 提交于 2019-12-24 00:56:04
  Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的 消息摘要 的函数。   HASH主要用于信息安全领域中加密算法,它把一些不同长度的信息转化成杂乱的128位的编码,这些编码值叫做HASH值. 也可以说,hash就是找到一种数据内容和数据存放地址之间的映射关系 基本概念    * 若结构中存在和关键字K相等的记录,则必定在f(K)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f为 散列函数 (Hash function),按这个思想建立的表为 散列表 。   * 对不同的关键字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),这种现象称冲突。具有相同函数值的关键字对该散列函数来说称做同义词。综上所述,根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象” 作为记录在表中的存储位置,这种表便称为散列表,这一映象过程称为散列造表或散列,所得的存储位置称散列地址。   *