(permission) end end # 版本1.0:使用 Hash 替代 Array 的 Role 类: # 这样做基于两处权衡,首先,因为哈希只存储的键,所以数组中的任何重复在转换成哈希的过程中都会丢失...# 每个迭代 reduce 都使用符号作为消息名称发送消息给累加器,同时将当前元素作为参数 def sum (enum) enum.reduce(0, :+) end # 考虑一下把一个数组的值全部转换为哈希的键...我从没有改变哈希对象,当我插入一个元素之后,哈希并么有改变,但是默认值改变了 # 这也是 keys 方法提示这个哈希是空但是访问不存在的键时却反悔了最近修改的值的原因 # 如果你真想插入一个元素并设置一个键...# 传给 Hash::new 的块可以有选择地接受两个参数:哈希本身和将要访问的键 # 这意味着我们如果想去改变哈希也是可的,那么当访问一个不存在的键时,为什么不将其对应的值设置为一个新的空数组呢?...:每当访问不存在的键时,块不仅会在哈希中创建新实体,同时还会创建一个新的数组 # 重申一遍:访问一个不存在的键会将这个键存入哈希,这暴露了默认值存在的通用问题: # 正确的检查一个哈希是否包含某个键的方式是使用
字典 4.1 字典的结构实现 Redis 的 Hash 类型键使用以下两种数据结构作为底层实现: 字典; 压缩列表 因为压缩列表比字典更节省内存,所以程序在创建新 Hash 键时,默认使用压缩列表作为底层...:当多个不同的键拥有相同的哈希值时,哈希表用一个链表将这些键连接起来。...——对字典进行迭代实际上就是对字典所使用的哈希表进行迭代: 迭代器首先迭代字典的第一个哈希表,然后,如果 rehash 正在进行的话,就继续对第二 个哈希表进行迭代。...unsigned int span; } level[]; } zskiplistNode; 为了适应 Redis 需要,对原生的跳跃表做了修改: 允许重复的 score 值:多个不同的...进行对比操作时,不仅要检查 score 值,还要检查 member :当 score 值可以重复时, 单靠 score 值无法判断一个元素的身份,所以需要连 member 域都一并检查才行。
需要注意的是,符号是不可变对象。 哈希(Hash) 哈希是一种非常有用且广泛使用的复合容器对象,可用于存储其他对象。我们通过键(key)来查找哈希中的值(value)。...声明哈希: H = {} 可以单独对key和value进行赋值操作: H[:a] = "123" puts H[:a] 也可以通过使用=>将键分配给值来创建哈希,用逗号分隔多个键值对,...也可以使用fetch方法,他和[]方法一样都可以查找某一个键的值,但是如果键对应的值不存在,会抛出异常。 ...: H = {} H[:a] = "123" puts H.keys() 也可以通过values返回一个带有哈希所有值的数组: H = {} H[:a] = "123" H["123"]...结语 字符、数字、布尔是不可变对象,而字符串、数组、哈希是可变对象,Ruby3中所有不可变对象的多个同值对象,都会指向同一个对象的内存地址。
Redis有以下几种常用的数据类型: redis数据是如何组织的 为了实现从键到值的快速访问,Redis 使用了一个哈希表来保存所有键值对。...如何使用 Redis的Set是一种无序、不重复元素的数据结构,类似于数学上的集合。它支持添加、删除和查询元素,并且能够对多个集合进行交集、并集、差集等操作。...散列函数(Hash Function): 在哈希表中,键通过散列函数计算得到一个哈希值(hash),这个哈希值被用作数组(桶)的索引。...Redis使用MurmurHash2等散列函数来均匀地将键分散到不同的桶中。 2. 桶数组: 哈希表底层维护了一个桶数组,每个桶中存储了一个或多个键值对。...获取所有键值对: 使用 HGETALL 命令可以获取哈希表中所有的键值对。 HGETALL user:id123 5. 增加或更新键的值: 使用 HINCRBY 命令可以为键的值增加一个整数。
(扩容机制:元素个数 >= 数组长度 * 0.75 后,长度扩容为原本的两倍 ) 新增元素时,根据元素的哈希值以及数组的长度计算出相应的位置:int index = (数组长度 - 1) & 哈希值;...双列集合 双列集合特点: ①双列集合一次需要存储一对数据,分别为键和值。 键不能重复,值可以重复。 键和值是一一对应的,每一个键只能找到自己对应的值。...(扩容机制:键值对个数 >= 数组长度 * 0.75 后,长度扩容为原本的两倍 ) 使用put()新增数据时,底层创建Entry对象存储 键和值,根据键的哈希值以及数组的长度计算出相应的位置:int index...如果不为null,通过equals()比较键的值,值一致会进行覆盖(键值对的旧value值被新value值覆盖),属性值不一致时,存入索引位置,形成链表。...---- ④LinkedHashMap集合 LinkedHashMap特点: 由键决定:存取有序,不重复,无索引 原理:底层数据结构依旧是哈希表(参考HashMap),只是每个键对元素又额外多了一个双链表的机制来记录存储的顺序
同样可变长数组。 Set接口 Set接口,不包含重复元素,没有索引,不能使用for遍历。 HashSet集合,哈希表结构(查询快),无序,不同步,使用迭代器或增强for遍历。...java1.8以后,哈希表使用数组,链表和红黑树提高查询速度。 数组结构:把元素进行了分组(相同哈希值的元素是一组,链表/红黑树结构把相同哈希值的元素连接到一起。每组数量大于8则将链表变成红黑树。...(键、值)(双列集合,一一对应,键值不能重复)。...keySet方法,返回的key会放到Set集合中,使用迭代器或增强for进行遍历key,键找值,进行遍历。...HashTable键和值都不为空,同步单线程,双列集合(区别于HashMap的允许空值等)。 哈希表的优点和利用在于其快速查找,配合Map可以快速统计。
SSCAN 命令用于迭代集合键中的元素。 HSCAN 命令用于迭代哈希键中的键值对。 ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。...从上面的示例可以看到, SCAN 命令的回复是一个包含两个元素的数组, 第一个数组元素是用于进行下一次迭代的新游标, 而第二个数组元素则是一个数组, 这个数组中包含了所有被迭代的元素。...在迭代一个足够大的、由哈希表实现的数据库、集合键、哈希键或者有序集合键时, 如果用户没有使用 MATCH 选项, 那么命令返回的元素数量通常和 COUNT 选项指定的一样, 或者比 COUNT 选项指定的数量稍多一些...在迭代一个编码为整数集合(intset,一个只由整数值构成的小集合)、 或者编码为压缩列表(ziplist,由不同值构成的一个小哈希或者一个小有序集合)时, 增量式迭代命令通常会无视 COUNT 选项指定的值...SCAN 命令返回的每个元素都是一个数据库键。 SSCAN 命令返回的每个元素都是一个集合成员。 HSCAN 命令返回的每个元素都是一个键值对,一个键值对由一个键和一个值组成。
key和val的指针,next指向下一个dictEntry形成链表,这个指针可以将多个哈希值相同的键值对链接在一起,由此来解决哈希冲突问题(链地址法)。...Hash对象只有同时满足下面两个条件时,才会使用ziplist(压缩列表):1.哈希中元素数量小于512个;2.哈希中所有键值对的键和值字符串长度都小于64字节。...; 上面源码可以简化成如下结构: 这个结构类似于JDK7以前的HashMap,当有两个或以上的键被分配到哈希数组的同一个索引上时,会产生哈希冲突。...Redis也使用链地址法来解决键冲突。即每个哈希表节点都有一个next指针,多个哈希表节点用next指针构成一个单项链表,链地址法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位。...Redis中的字典使用hashtable作为底层实现的话,每个字典会带有两个哈希表,一个平时使用,另一个仅在rehash(重新散列)时使用。随着对哈希表的操作,键会逐渐增多或减少。
通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。...Map集合存储元素是键值成对出现的,Map集合的键是唯一的,值是可重复的。...Entry键值对对象 我们已经知道,Map中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在Map中是一一对应关系,这一对对象又称做Map中的一个Entry(项)。...Entry将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。...既然Entry表示了一对键和值,那么也同样提供了获取对应键和对应值得方法: public K getKey():获取Entry对象中的键。
,里面有着key和val的指针,next指向下一个dictEntry形成链表,这个指针可以将多个哈希值相同的键值对链接在一起,由此来解决哈希冲突问题(链地址法)。...4.2 ziplist(压缩列表) 当一个列表键只包含少量列表项,且是小整数值或长度比较短的字符串时,那么redis就使用ziplist(压缩列表)来做列表键的底层实现。...Hash对象只有同时满足下面两个条件时,才会使用ziplist(压缩列表):1.哈希中元素数量小于512个;2.哈希中所有键值对的键和值字符串长度都小于64字节。...Redis也使用链地址法来解决键冲突。即每个哈希表节点都有一个next指针,多个哈希表节点用next指针构成一个单项链表,链地址法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位。...Redis中的字典使用hashtable作为底层实现的话,每个字典会带有两个哈希表,一个平时使用,另一个仅在rehash(重新散列)时使用。随着对哈希表的操作,键会逐渐增多或减少。
dictEntry:Redis给每个key-value键值对分配一个dictEntry,里面有着key和val的指针,next指向下一个dictEntry形成链表,这个指针可以将多个哈希值相同的键值对链接在一起...4.2 ziplist(压缩列表) 当一个列表键只包含少量列表项,且是小整数值或长度比较短的字符串时,那么redis就使用ziplist(压缩列表)来做列表键的底层实现。 ?...Hash对象只有同时满足下面两个条件时,才会使用ziplist(压缩列表):1.哈希中元素数量小于512个;2.哈希中所有键值对的键和值字符串长度都小于64字节。...这个结构类似于JDK7以前的HashMap,当有两个或以上的键被分配到哈希数组的同一个索引上时,会产生哈希冲突。 Redis也使用链地址法来解决键冲突。...Redis中的字典使用hashtable作为底层实现的话,每个字典会带有两个哈希表,一个平时使用,另一个仅在rehash(重新散列)时使用。随着对哈希表的操作,键会逐渐增多或减少。
dictEntry:Redis给每个key-value键值对分配一个dictEntry,里面有着key和val的指针,next指向下一个dictEntry形成链表,这个指针可以将多个哈希值相同的键值对链接在一起...4.2 ziplist(压缩列表) 当一个列表键只包含少量列表项,且是小整数值或长度比较短的字符串时,那么redis就使用ziplist(压缩列表)来做列表键的底层实现。 ?...Hash对象只有同时满足下面两个条件时,才会使用ziplist(压缩列表):1.哈希中元素数量小于512个;2.哈希中所有键值对的键和值字符串长度都小于64字节。...这个结构类似于JDK7以前的HashMap,当有两个或以上的键被分配到哈希数组的同一个索引上时,会产生哈希冲突。Redis也使用链地址法来解决键冲突。...Redis中的字典使用hashtable作为底层实现的话,每个字典会带有两个哈希表,一个平时使用,另一个仅在rehash(重新散列)时使用。随着对哈希表的操作,键会逐渐增多或减少。
dictEntry:Redis给每个key-value键值对分配一个dictEntry,里面有着key和val的指针,next指向下一个dictEntry形成链表,这个指针可以将多个哈希值相同的键值对链接在一起...Hash对象只有同时满足下面两个条件时,才会使用ziplist(压缩列表):1.哈希中元素数量小于512个;2.哈希中所有键值对的键和值字符串长度都小于64字节。...这个结构类似于JDK7以前的HashMap,当有两个或以上的键被分配到哈希数组的同一个索引上时,会产生哈希冲突。Redis也使用链地址法来解决键冲突。...Redis中的字典使用hashtable作为底层实现的话,每个字典会带有两个哈希表,一个平时使用,另一个仅在rehash(重新散列)时使用。随着对哈希表的操作,键会逐渐增多或减少。...---O(N) slen:intsetlen ---O(1) intset底层实现为有序,无重复数组保存集合元素。
此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)...特点: 键无序,唯一,类似于Set集合 值有序,可重复,类似于List 底层数据结构是哈希表,保证键唯一 允许键为null,值为null HashMap和Hashtable的区别 HashMap...是不安全的不同步的效率高的 允许null键和null值 Hashtable是安全的同步的效率低的 不允许null键和null值 底层都是哈希表结构 LinkedHashMap集合 Map 接口的哈希表和链接列表实现...特点: 键有序,唯一, 值有序,可重复,类似于List 底层数据结构是哈希表和链表,哈希表保证键唯一,链表保证键有序 TreeMap集合 基于红黑树 (red-black tree) 数据结构实现...但是如果你不清楚,只能通过迭代内部全部元素然后进行条件判断查找,那么List就要慢的多,因为他要从头到尾一个个的元素去查,直到找到满足你的要求的那个元素,而Map则不需要迭代,因为Map有键,直接取键对应的值
(元素);Map 是一种键-值映射表,当我们调用 put(K key, V value) 方法时,就把 key 和 value 做了映射并放入 Map 。...HashMap 中,null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null。...哈希值的使用不同 : HashTable 直接使用对象的 hashCode。HashMap 重新计算 hash 值。...这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。...简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。所有散列函数都有如下一个基本特性:根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。
在输入数据完全不同的情况下,输出的哈希值有可能是相同的,这种少数特殊情况称为“哈希冲突”。 ? 同时,哈希值是不可逆的,也就是说,通过哈希值不可能反向推算出原本的数据。...我们重点来看哈希函数的压缩函数,这也是其核心功能。 对于消息调度中的每个词,我们都使用 “状态寄存器” 中的当前值来计算两个新的临时词(设为 T_1 和 T_2)。 ?...在计算了两个临时词之后,将状态寄存器中的值移至下一个位置,并更新寄存器: 状态寄存器中的第一个值变为 T_1 + T_2,同时状态寄存器中的第五个值已添加了 T_1。...这即是一轮压缩,对于信息调度中的每个词该过程都会重复一次。 在压缩了整个消息调度之后,我们将得到的哈希值添加到初始哈希值中,由此得出消息块的最终哈希值。...但如果还有其他消息块要处理,则将当前哈希值在下一次压缩中用作初始哈希值。如下图所示: ?
一个映射不能包含重复的键;每个键最多只能映射到一个值。...2.3 Map常用实现类 2.3.1 HashMap 基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序。...存储特点: 相对无序存储,元素以键值对形式存在,键不可以重复,值可以重复,元素整体排重,可以快速的通过键查找到所对应的值,通过哈希表实现的集合。...2.3.3 Hashtable 此类实现一个哈希表,该哈希表将键映射到相应的值。任何非null对象都可以用作键或值。 存储特点: 相对无序存储,元素排重,通过哈希表实现的集合。...Comparator:比较器,compare( o1, o2){ } 如果返回值为0 重复元素 Map 特点:存储键值对 ,键不能重复,一个键对应一个值,值可以重复 ----HashMap:存储结构
领取专属 10元无门槛券
手把手带您无忧上云