問(wèn)題描述
我了解 HashMap 如何工作的基礎(chǔ)知識(shí) - hm.put(obj) 根據(jù) obj.hashCode 值找到正確的存儲(chǔ)桶來(lái)放置對(duì)象.然后在該桶中,如果另一個(gè)對(duì)象 .equals(obj) 則替換它,如果沒(méi)有將其添加到桶中.
I understand the basics of how a HashMap works - hm.put(obj) finds the correct bucket to place the object into, based on the obj.hashCode value. Then within that bucket if another object .equals(obj) then replace it, if not add it to the bucket.
但我不清楚 HashMap.put 和 HashMap.get 如何可以是常數(shù)時(shí)間 O(1).據(jù)我了解,存儲(chǔ)桶的數(shù)量應(yīng)基于哈希碼,因此將 100 個(gè)對(duì)象放入哈希圖中將(大致)創(chuàng)建 100 個(gè)存儲(chǔ)桶(我確實(shí)了解哈希碼有時(shí)會(huì)發(fā)生沖突,因此它可能小于 100 但不是經(jīng)常).
But I am unclear on how HashMap.put and HashMap.get can be constant time O(1). As I understand it, the number of buckets should be based on the hashcodes, so putting 100 objects into a hashmap will (roughly) create 100 buckets (I do understand there are sometimes collisions in hashcodes, so it could be less than 100 but not often).
因此,隨著添加到哈希圖中的對(duì)象數(shù)量的增加,桶的數(shù)量也會(huì)增加 - 由于沖突很少,這并不意味著桶的數(shù)量幾乎隨著添加的對(duì)象數(shù)量線性增長(zhǎng),其中case HashMap.put/HashMap.get 將是 O(n),因?yàn)樗仨氃谡业秸_的存儲(chǔ)桶之前搜索每個(gè)存儲(chǔ)桶.
So as the number of objects added to a hashmap grows, so does the number of buckets - and since collisions are rare then doesn't that mean that the number of buckets grows almost linearly with the number of objects added, in which case HashMap.put/HashMap.get would be O(n) as it has to search over every bucket before it finds the right one.
我錯(cuò)過(guò)了什么?
推薦答案
這是我的兩分錢,朋友.以您認(rèn)為數(shù)組的方式來(lái)考慮 HashMap.事實(shí)上,它是一個(gè)數(shù)組.如果我給你索引 11,你不必遍歷數(shù)組來(lái)查找索引 11 處的對(duì)象.你只需直接去那里.這就是 HashMap 的工作原理:訣竅是使索引與值相同——本質(zhì)上.
Here is my two cent, friend. Think of a HashMap the way you think of an array. In fact, it is an array. If I give you index 11, you don't have to iterate through the array to find the object at index 11. You simply go there directly. That's how a HashMap works: the trick is to make the index the same as the value -- essentially.
這就是哈希碼的用武之地.讓我們看一下哈希函數(shù)是單位乘數(shù)(即 1)的簡(jiǎn)單情況.然后,如果你有 0 到 99 的值并且你想將它們存儲(chǔ)在一個(gè)數(shù)組中,那么它們將分別存儲(chǔ)在索引 0 到 99 處.因此 put 和 get 顯然是 O(1),因?yàn)楂@取和放入數(shù)組是 O(1).現(xiàn)在讓我們想象一個(gè)不那么簡(jiǎn)單的散列函數(shù),比如 y = x+2.所以在這種情況下,值 0 到 99 將存儲(chǔ)在索引 2 到 101 處.這里給定一個(gè)值,比如 11,您必須計(jì)算散列以找到它或放入它(散列為 11+2 =13).好吧,哈希函數(shù)正在做一些工作來(lái)計(jì)算給定值的正確索引(在我們的例子中 y = x+2= 11+2=13).但是,這項(xiàng)工作所付出的努力與您擁有多少數(shù)據(jù)點(diǎn)無(wú)關(guān).如果我需要放置 999 或 123,則單個(gè) put 或 get 的工作量仍然相同: y= x+2:我每次執(zhí)行 put 或 get 時(shí)只需添加兩個(gè):這是恒定的工作.
So that is where a hashcode comes in. Let's look at the trivial case where your hash function is a unit multiplier (i.e. 1). Then if you have the values 0 to 99 and you want to store them in an array, then they will be stored at indices 0 to 99 respectively. So that a put and a get is clearly O(1) since getting and putting things in an array is O(1). Now let's imagine a less trivial hash function, say, y = x+2. So in this case the values 0 to 99 will be stored at indices 2 to 101. Here given a value, say 11, you must compute the hash to find it or put it (the hash being 11+2 =13). So okay, the hash function is doing some work to calculate the correct index given the value (in our case y = x+2= 11+2=13). But the amount of effort that goes into that work has nothing to do with how many data points you have. If I need to put 999 or 123, the amount of work for a single put or get is still the same: y= x+2: I only have to add two each time I do a put or a get: that's constant work.
您的困惑可能是您想一次放置 n 個(gè)值.那么在這種情況下,每個(gè) put 仍然是常量 c
.但是 c
乘以 n 是 c*n
=O(n).因此, n 與 put 本身無(wú)關(guān),而是您同時(shí)進(jìn)行 n 個(gè) put.我希望這個(gè)解釋會(huì)有所幫助.
Your confusion may be that you want to put n values at once. Well in that case each put is still constant c
. But c
multiplied by n is c*n
=O(n). So the n has nothing to do with the put itself, but rather that you are making n puts all at once. I hope this explanation helps.
這篇關(guān)于Java HashMap 如何對(duì)“get"執(zhí)行恒定時(shí)間查找 O(1)?操作?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!