java中关于散列表的详细介绍
什么是散列表
散列表,也叫作哈希表(Hash Table),是一种提供键(Key)和值(Value)的映射关系的数据结构,只要给出一个Key,就可以高效查找到它所匹配的Value,时间复杂度接近于O(1)。
在线学习视频推荐:java视频
散列表的工作原理
散列表在本质上是一个数组。我们知道数组可以根据下标来进行随机访问,如a[0], a[1], a[2], a[3], a[4],通过这样来访问,因此其查询效率非常高。而在散列表中,当我们给出一个key的时候,也能立即查询到对应的value。这时我们就需要一个“中转站”,通过某种方式,把Key和数组下标进行转换,而这个中转站就是哈希函数。
不同的语言中,哈希函数的实现方式是不同的。Java中使用的是HashMap
。
在Java及大多数的面向对象的语言中,每个对象都有属于自己的hashcode
,用以区分不同的对象,而这个hashcode是一个整形变量。此时我们就需要将这个整形变量转化成数组的下标,最简单的转化方式是对数组长度进行取模。
公式如下:
index = HashCode(key) % Array.length
举个例子:
给出一个长度为8的数组,我们要查找key为"001121"所对应的Vaule,而"001121"的hashcode为1420036703,那么就可通过下面的计算先得到数组下标:
index = HashCode("001121")%Array.length = 1420036703 % 8 = 7
散列表的读写操作
1.写操作
写操作就是在散列表中插入新的键值对(jdk中叫做Entry)。
具体的做法是:通过哈希函数将key值转化为数组下标,然后在数组的该位置处插入Entry(注意是Entry键值对Key+Value,而不仅仅是Value)。可想而知,不同的key值可能会转化为相同的下标,那么此时就成为哈希冲突。
解决哈希冲突常用的方法是开放寻址法和链表法。
开放寻址法的基本思路是:当发生哈希冲突时,就把Entry放到下一个数组中为空的位置,也就是逐个往后移动。
链表法(应用在Java的HashMap集合类中)的基本思想是:数组中的每个元素不仅是一个Entry对象,同时也是一个链表的头节点。每个Entry对象通过next指针指向它的下一个Entry节点。当新来的Entry对象映射到与之冲突的数组位置时,只需要插入到对应的链表中即可。
2.读操作
读操作与写操作对应 ,只需特别处理冲突情况即可。
具体的思路为:通过哈希函数,将待查找的Key值转化为数组下标,然后检查数组中该位置的Key值是否为我们要找的Key,若是,则找到,可以返回该Entry的Value值;否则,沿着链表继续往下查找,看有没有对应的Key值。
例如,我们要查找Key为002936所对应的value时,先将Key转化为数组下标,得到下标为2,检查该元素,发现该元素的Key为002947,不是我们要查询的Key,那么继续沿着链表往下查找。
3.扩容
我们知道数组扩容,是当数组中的元素个数达到数组的最大长度时需要对数组扩容,那么散列表什么时候扩容呢?
当经过多次元素插入,散列表达到一定的饱和度时,发生哈希冲突的概率会变大,此时大量的元素拥挤在相同的数组下标位置,这对后序的插入和查询操作的性能产生很大的影响,此时就需要对散列表扩容。
影响散列表扩容的因素为:
Capacity,即HashMap的当前长度
LoadFactor,即HashMap的负载因子,默认值为0.75
扩容需要满足的条件:
HashMap.Size >= Capacity X LoadFactor
简单解释为:当哈希表中的条目数超出了当前容量与其加载因子的乘积时,并且要存放的位置已经有元素了(哈希碰撞),这两个条件满足时,需要进项扩容,会将容量扩大为原来的两倍。加载因子默认值0.75,是在空间和时间上的一个折中,加载因子过高(发生冲突可多存放在链表),虽然减少了空间成本,但也增加了查询成本。
扩容的步骤:
扩容不是简单地把散列表的长度扩大,而是经历了下面两个步骤:
1.扩容,创建一个新的Entry空数组,长度时原数组的2倍;
2.重新Hash,遍历原Entry数组,所有的Entry重新Hash到新数组中。
经过扩容,原本拥挤的散列表重新变得稀疏,原有的Entry也重新得到了尽可能均匀的分配。需要注意的是,关于HashMap的实现,JDK8和以前的版本有着很大的不同。当多个Entry被Hash到同一个数组下标位置时,为了提高插入和查找的效率,HashMap会把Entry的链表转化为红黑树这种数据结构。
相关文章教程推荐:java语言入门
Atas ialah kandungan terperinci java中关于散列表的详细介绍. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Panduan untuk Square Root di Java. Di sini kita membincangkan cara Square Root berfungsi di Java dengan contoh dan pelaksanaan kodnya masing-masing.

Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

Panduan untuk Penjana Nombor Rawak di Jawa. Di sini kita membincangkan Fungsi dalam Java dengan contoh dan dua Penjana berbeza dengan contoh lain.

Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

Panduan untuk TimeStamp to Date di Java. Di sini kita juga membincangkan pengenalan dan cara menukar cap waktu kepada tarikh dalam java bersama-sama dengan contoh.
