首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

编程思想 之「容器深入研究」

由于存储一组元素最快的数据结构是数组,因此使用数组来表示的信息。但数组在初始化容量之后,就不能进行扩容了,而我们希望在Map中保存数量不确定的值,这该如何是好?...答案就是:数组并不保存本身,而是通过对象生成一个数字,将其作为数组的下标。这个数字就是码,它可以通过hashCode()方法生成。为解决数组容量的问题,不同的可以生产相同的下标。...因此,数组多大就不重要了,任何总能在数组中找到它的位置。 于是查询一个值的过程首先就是计算码,然后使用码查询数组。...这部分的查询自然会比较慢,但是,如果函数好的话,数组的每个位置就只有较少的值。...由于列表中的“槽位”通常称为桶位,因此我们将表示实际列表的数组命名为bucket,而且为了让均匀分布,桶的数量通常使用质数。

69030
您找到你想要的搜索结果了吗?
是的
没有找到

Java漫谈-容器

WeakHashMap 弱(weak key)映射,允许释放映射所指向的对象;这是为解决某类特殊问题而设计的。如果映射之外没有引用指向某个“”,则此键可以被垃圾收集器回收。...的价值在于速度 使得查询得意快速进行。它将保存在某处,以便能够快速找到。存储一组元素最快的数据结构是数组,所以用它来保存的信息(而不是本身)。...而是通过对象生成一个数字,将其作为数组的下标,这个数字就是码,由定义在Objcet中的、且可能由你覆盖的hashCode()方法(在计算机科学的术语中成为函数)生成。...不同的可以产生相同的下标,可能会冲突,但数组多大就不重要了,任何都能找到自己的位置。 查询一个值的过程首先是计算码,然后使用码查询数组。...通常冲突由外部链接处理:数组并不直接保存值,而是保存值的list。然后对list中的值使用equals()方法进行线性查询,这部分查询自然比较慢,但如果函数好的话,数组的每个位置只有少量的值。

1.5K10

列表结构 字典与集合

列表上插入、删除和取用数据都非常快,但是对于查找操作来说却效率地下 列表是基于数组进行设计的,数组的长度是预先设定,如有需要可随时增加。所有元素根据和该元素对应的,保存在数组的特定位置。...使用列表存储数据时,通过一个函数将映射为一个数字,这个数字范围是0到列表长度。函数的选择依赖于的数据类型,在此我们对的hash值对数组长度区余的方法。列表的数组究竟应该有多大?...理想情况下,函数会将每个键值映射为唯一的数组索引,然而,的数量是无限的,列表的长度是有限的,一个理想的目标是让函数尽量将均匀地映射到列表中。...即使使用一个高效的函数,仍然存在将两个映射为同一个值的可能,这种现象称为碰撞(collision)。当碰撞发生时,我们需要方案去解决。...即使两个后的值相同,依然被保存在同样的位置,只不过它们在第二个数组中的位置不一样罢了。 线性探查:当发生碰撞时,线性探测法检测列表的下一个位置是否为空。

98010

Java数据结构与算法解析(十二)——列表

这是对于简单的的情况,我们将其扩展到可以处理更加复杂的类型的的查找算法有两个步骤: 1.使用函数将被查找的转换为数组的索引。...只需要调整哈希函数算法即可在时间和空间上做出取舍。 函数和的类型有关。对于每种类型的我们都需要一个与之对应的函数。 函数 1. 正整数 获取正整数值最常用的方法是使用除留余数法。...通过函数,我们可以将转换为数组的索引(0-M-1),但是对于两个或者多个具有相同索引值的情况,我们需要有一种方法来处理这种冲突。...对采用拉链法的哈希实现的查找分为两步,首先是根据值找到等一应的链表,然后沿着链表顺序找到相应的。...当我们查找某个时,首先通过函数得到一个数组索引后,之后我们就开始检查相应位置的是否与给定相同,若不同则继续查找(若到数组末尾也没找到就折回数组开头),直到找到该或遇到一个空位置。

1.1K10

13.2 具体的集合

在Java中,列表用链表数组实现,每个列表称为桶(bucket)。要想查找表中对象的位置,就需要计算它的码,然后与桶中的总数取余,所得到的结果就是保存这个元素的桶的索引。...如果列表太满,就需要(rehashed)。如果要对列表再,就需要创建一个桶更多的表,并将所有的元素都插入到这个表中,然后丢弃原来的表。...,然后遍历集中的不同单词,最后打印出单词的数量,单词以随机的顺序出现。...映射表对进行,树映射表用的整体顺序对元素进行排序,并将其组织成搜索树。或比较函数只能作用于。与关联的值不能进行或比较。...与集一样,稍微快一些,如果不需要按照排列顺序访问,就最好选用。   每当往映射表中添加对象的时候,必须同时提供一个。在这里,是一个字符串,对应的值是Employee对象。

1.8K90

漫画 | 什么是列表(哈希表)?

列表在某种意义上需要数组空间可以比直接寻址表要少的很多。 函数是将所有元素的转换为自然数,自然数的数集是{0,1,2,……}。 如果所有元素的是正整数,最常用的方法是求模(除留余数法)。...我们选择长度为素数M的数组,对于任意正整数k,计算k mod M求得余数; 如果所有元素的是浮点数,我们将它表示为二进制数,忽略小数点再转化为十进制,然后求模; 如果所有元素的是字符串,可以将它字符串里面的每一个字符通过...线性探测法是,通过函数得到值,检查这个值是否被占用,如果被占用,将索引增大,到达数组结尾时折回数组的开头,直到找到没有被占用的值。...二次探测采用的函数为: 双重探测采用的函数为: 其中 簇,是指元素在插入数组后聚集成的一组连续的条目,决定线性探测的平均成本。...如下图所示,插入之前已经看到了两个比较长的簇,如果待插入元素通过函数得到的值正好是这两个簇中的第一个位置,就需要探测很多次才能找到空的位置;如果落在了两个簇间的只有一个空位置,那就产生了更长的

79311

Java集合详解【面试+工作】

HashMap: Map 主要用于存储(key)值(value)对,根据得到值,因此键不允许重复,但允许值重复。...列表算法的基本思想是:以结点的关键字为自变量,通过一定的函数关系(函数)计算出对应的函数值,以这个值作为该结点存储在列表中地址。...当列表中的元素存放太满,就必须进行再,将产生一个新的列表,所有元素存放到新的列表中,原先的列表将被删除。...在Java语言中,通过负载因子(load factor)来决定何时对列表进行再。例如:如果负载因子0.75,当列表中已经有75%位置已经放满,那么将进行再。...,违反“相等的对象必须具有相等的码”。

1.9K60

Python 算法基础篇之查找算法:哈希表、哈希集合、哈希映射

查找算法概述 查找算法是一种基于函数的查找技术,它将映射到数组的索引位置,从而实现快速的查找、插入和删除操作。在查找算法中,关键的组成部分是函数,它负责将映射到数组的索引位置。...然而,它也有一些局限性,首先是函数的设计需要满足一致性和均匀性的要求,以保证良好的性能。其次,查找算法的空间消耗较大,因为需要维护一个数组来存储数据。 2....哈希表的概念 哈希表是查找算法的一种常见应用,它是一种数据结构,用于存储键值对。在哈希表中,通过函数将映射到数组的索引位置,然后将键值对存储在该位置。...当需要判断元素是否存在于哈希集合中时,可以通过函数计算出元素的哈希值,然后查找哈希集合中的索引位置,如果存在则表示元素存在于哈希集合中。 4....当需要查找或操作对应的值时,可以通过函数计算出的哈希值,然后查找哈希映射中的索引位置,从而快速地获取对应的值。 5.

21800

Java 集合源码解析 - ConcurrentHashMap(JDK7)

* 如果时发生碰撞,碰撞的 HashEntry 对象就以链表的形式链接成一个链表 * table 数组数组成员代表映射表的一个桶 * 每个 table 守护整个...在 ConcurrentHashMap 中,不允许用 null 作为/值 ConcurrentMaps(ConcurrentHashMaps,ConcurrentSkipListMaps)不允许使用...先经过一次再 然后使用该值通过运算定位到Segment 最后通过算法定位到该元素. public V get(Object key) { Segment s;...插入操作需经历两个步骤: 判断是否需要对Segment里的HashEntry数组进行扩容 定位添加元素的位置,然后将其放在HashEntry数组 是否需要扩容 在插入元素前会先判断Segment里的...如何扩容 在扩容的时候,首先会创建一个容量是原来两倍的数组,然后将原数组里的元素进行再后插入到新的数组

74820

Java之HashMap详解

这个映射函数叫做函数,存放记录的数组叫做列表。 HashMap实现原理 ? HashMap主要是以数组和链表实现的。...每个列表被称为桶要想査找表中对象的位置, 就要先计算它的码, 然后与桶的总数取余, 所得到的结果就是保存这个元素的桶的索引。 解释:hashmap是以一个数组和链表储存的。...那么现在加入数组有10个长度,比方说现在需要add的一个key=1,vallue=“张三”的元素 列表数组的下标=1.hashcode()%列表数组.length,这个就是数组的下标。...这种现象被称为冲突( hashcollision) o 这时, 需要用新对象与桶中的所有对象进行比较,査看这个对象是否已经存在。...如果码是合理且随机分布的, 桶的数目也足够大, 需要比较的次数就会很少。

1.3K20

.NET中的泛型集合

尽管不允许,但GetKeyForItem可以返回空(如果类型为引用类型),这时将忽略(并且无法通过获取项)。...如果合理,通过访问的复杂度也为O(1);而如果所有码都相等,由于要依次检查各个是否相等,因此最终的复杂度为O(n)。在大多数实际场合中,这都不是问题。...下面是我们分析选择函数的两大要素: 数据分布。这是衡量函数生成值好坏的尺度。分析这个需要知道在数据集内发生碰撞冲突的数量,即非唯一的值。 函数的效率。...这个方法的主要思想是通过遍历数据,然后以某种计算形式来构造值。通常情况下是乘以某个素数的乘法形式。如下图所示: 目前来说,还没有数学方法能够证明素数和函数之间的关系。...当进行扩容时,列表内部要重新 new 一个更大的数组然后把原来数组的内容拷贝到新数组,并进行重新。如何 new 这个更大的数组也有讲究。列表的初始容量一般来讲是个素数。

14320

Redis:09---Hash对象

一、哈希对象简介 几乎所有的编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组 哈希又称 在Redis中,哈希类型是指键值本身又是一个键值对结构,形如value={{field1...一些特点: 存储多个键值对之间的映射,并且键值对不允许重复 在某一个固定的key中,其对应value中的field也不允许重复 存储的值既可以是字符串也可以是数字值 用户同样可以对存储的数字值执行自增操作或自减操作...因为“文档、行、”这三者都允许用户同时访问或修改一个或多个域 注意:哈希类型中的映射关系叫作field-value,注意这里的value是指field对应的值,不是对应的值,请注意value在不同上下文的作用...当field个数超过512,内部编码也会由ziplist变为hashtable 四、字符串和的比较与选择 的优点 的最大优势,只需要在数据库里面创建一个,就可以把任意多的字段和值存储到里面...当然,用户也可以选择把数据存储在中,然后将类似 SETRANG E、GETRANGE 这样的操作交给客户端执行 如果程序需要存储的数据项比较多,并且你希望尽可能地减少存储数据所需的内存,就应该优 先考虑使用

90320

Rails路由

非资源式路由 和资源路由自动生成一系列路由不同,这时需要分别声明各个路由,非资源路由可以把任意URL地址映射到控制器动作的路由。...动态片段 声明普通路由时,允许使用多个动态片段,动态片段会传入params,以便在控制器动作中使用: get 'photos/:id/:user_id', to: 'photos#show' /photos.../1/2 请求会被映射到 photos#show 动作上,这时 params[:id] 的值是 1 ,params[:user_id] 的值是 2 查询字符串 params 也包含了查询字符串中的所有参数...: '2'} 定义默认值 :defaults 选项设定的列为路由定义默认值,未通过动态片段定义的参数也可以指定默认值 get 'photos/:id', to: 'photos#show', defaults...: {format: 'jpg'} Rails会把 /photos/12 路径映射到 Photos#show 动作上,并把 params[:format] 设为 'jpg' 当然 defaults 还有块的形式

4.4K20

看动画学算法之:hashtable

简介 java中和hash相关并且常用的有两个类hashTable和hashMap,两个类的底层存储都是数组,这个数组不是普通的数组,而是被称为列表的东西。 列表是一种将映射到值的数据结构。...它用哈希函数来将映射到小范围的指数(一般为[0..哈希表大小-1])。同时需要提供冲突和对冲突的解决方案。 今天我们来学习一下列表的特性和作用。 文末有代码地址,欢迎下载。...我们可以使用函数来解决这个问题。 通过使用函数,我们可以: 将一些非整数映射成整数, 将大整数映射成较小的整数。 通过使用函数,我们可以有效的减少存储数组的大小。...完美的函数是值之间的一对一映射,即根本不存在冲突。 当然这种情况是非常少见的,如果我们事先知道了函数中要存储的key,还是可以办到的。...我们遍历原始哈希表中的所有,重新计算新的哈希值,然后将键值重新插入新的更大的哈希表中,最后删除较早的较小哈希表。

77720

算法原理系列:列表

所以,从以上两点,你能总结出两个性质: 第一,列表是典型的用空间来换时间的数据结构,如果内存无限大,有时你甚至可以不用对做映射处理,只需要一次查找就能找到对应的value。...第二,映射函数是为了寻找数组下标的关系,使得查找转换成在该数组范围内的索引[0,M-1],可分配的数组大小为M。 ? 存在两个问题,映射函数怎么找,以及对应的求得的映射值相同时,该如何处理。...假设J:我们使用的函数能够均匀并独立地将所有的分布于0到M-1之间。 ?...折叠法 将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为地址。...冲突检测线性探测法 开放地址列表中最简单的方法叫做线性探测法:当碰撞发生时(当一个值已经被另一个不同的占用),我们直接检查列表中的下一个位置(将索引值加1)。

46540

Redis 字典

如上图所示,我们把学号作为key,通过截取学号后四位的函数后计算后得到索引下标,将数据存储到数组中。当我们按照键值(学号)查找时,只需要再次计算出索引下标,然后取出相应数据即可。以上便是思想。...列表中查找元素的时候,我们通过函数求出要查找元素的键值对应的值,然后比较数组中下标为值的元素和要查找的元素。如果相等,则说明就是我们要找的元素;否则就顺序往后依次查找。...1.3.2 链表法 链表法是一种比较常用的冲突解决办法,Redis使用的就是链表法来解决冲突。链表法的原理是:如果遇到冲突,他就会在原地址新建一个空间,然后以链表结点的形式插入到该空间。...2.2 Redis如何解决冲突 2.2.1 链表法 当有两个或以上的被分配到列表数组同一个索引上时,就发生了冲突。Redis使用链表法解决冲突。...2、将保存在ht0中的键值对重新计算值和索引值,然后放到ht1指定的位置上。

1.6K84

算法与

由于速度的瓶颈是对“”进行查询,而存储一组元素最快的数据结构是数组,所以用它来代表的信息,注意:数组并不保存“”的本身。而通过“”对象生成一个数字,将其作为数组的下标索引。...这个数字就是码,由定义在Object的hashCode()生成(或成为函数)。同时,为了解决数组容量被固定的问题,不同的“”可以产生相同的下标。那对于数组来说?...原来数组并不直接保存“值”,而是保存“值”的 List。然后对 List中的“值”使用equals()方法进行线性的查询。...HashMap和hashSet的构造器允许你制定负载因子。这意味着,当负载达到制定值时,容器会自动成倍的增加容量,并将原有的对象重新分配,存入新的容器内(这称为“重”rehashing)。...也就是说,它必须基于对象的内容生成码。 应该产生分布均匀的码。如果码都集中在一块,那么在某些区域的负载就会变得很重。

1.4K60

Hash

为了速度而 HashMap速度总所周知是非常快的,但是为什么会这么快,是因为它的技术,下面简单理解一下知识 的价值在于速度,使得查询得以快速。...一般容器查询的速度的瓶颈位于的查询,采取的做法一般是对进行排序,但则不是 的特点 的做法,通常把保存到某个地方,存储一组元素最快的数据结构就是数组,所以用它来保存的信息(不是本身...故而,有个难题,如果用数组保存不确定元素大小的值。 的做法,数组不保存本身,而是通过对象生成一个随机数字,用作数组的下标,这个数字就是我们通常见到的hashCode。...通常,冲突由外部链接处理,数组不直接保存值,而是保存值的list,然后遍历list,进行equals线性查询,这部分的查询自然会比较慢,但是如果函数好的话,每个位置都只有较少的值。...slot 和 bucket 中的槽位(solt)通常称为桶位,以内实际列表的数组名称为bucket, 桶的数量都使用质数。

63710
领券